diff --git a/CMakeLists.txt b/CMakeLists.txt index d23ea604d..c8527a8a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ find_package(SwiftCollections QUIET) find_package(SwiftSyntax CONFIG REQUIRED) find_package(SwiftASN1 CONFIG REQUIRED) find_package(SwiftCrypto CONFIG REQUIRED) +find_package(SwiftToolsProtocols CONFIG REQUIRED) include(SwiftSupport) diff --git a/Package.swift b/Package.swift index 2c47d6c03..85095efe0 100644 --- a/Package.swift +++ b/Package.swift @@ -20,8 +20,6 @@ var globalSwiftSettings: [SwiftSetting] { var products: [Product] = [ .executable(name: "sourcekit-lsp", targets: ["sourcekit-lsp"]), .library(name: "_SourceKitLSP", targets: ["SourceKitLSP"]), - .library(name: "BuildServerProtocol", targets: ["BuildServerProtocol"]), - .library(name: "LSPBindings", targets: ["LanguageServerProtocol", "LanguageServerProtocolJSONRPC"]), .library(name: "InProcessClient", targets: ["InProcessClient"]), .library(name: "SwiftSourceKitPlugin", type: .dynamic, targets: ["SwiftSourceKitPlugin"]), .library(name: "SwiftSourceKitClientPlugin", type: .dynamic, targets: ["SwiftSourceKitClientPlugin"]), @@ -42,9 +40,9 @@ var targets: [Target] = [ "BuildServerIntegration", "Diagnose", "InProcessClient", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), "SKOptions", "SourceKitLSP", "ToolchainRegistry", @@ -56,37 +54,16 @@ var targets: [Target] = [ linkerSettings: sourcekitLSPLinkSettings ), - // MARK: BuildServerProtocol - - .target( - name: "BuildServerProtocol", - dependencies: [ - "LanguageServerProtocol" - ], - exclude: ["CMakeLists.txt"], - swiftSettings: globalSwiftSettings - ), - - .testTarget( - name: "BuildServerProtocolTests", - dependencies: [ - "BuildServerProtocol", - "LanguageServerProtocol", - "SKTestSupport", - ], - swiftSettings: globalSwiftSettings - ), - // MARK: BuildServerIntegration .target( name: "BuildServerIntegration", dependencies: [ - "BuildServerProtocol", - "LanguageServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", - "SKLogging", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKUtilities", "SourceKitD", @@ -94,6 +71,7 @@ var targets: [Target] = [ "ToolchainRegistry", "TSCExtensions", .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ] + swiftPMDependency([ .product(name: "SwiftPM-auto", package: "swift-package-manager"), @@ -107,7 +85,7 @@ var targets: [Target] = [ name: "BuildServerIntegrationTests", dependencies: [ "BuildServerIntegration", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "SKOptions", "SKTestSupport", "SourceKitLSP", @@ -117,13 +95,6 @@ var targets: [Target] = [ swiftSettings: globalSwiftSettings ), - // MARK: CAtomics - - .target( - name: "CAtomics", - dependencies: [] - ), - .target( name: "CCompletionScoring", dependencies: [] @@ -135,14 +106,15 @@ var targets: [Target] = [ name: "ClangLanguageService", dependencies: [ "BuildServerIntegration", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", - "SKLogging", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SourceKitLSP", "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", ] + swiftSyntaxDependencies(["SwiftSyntax"]), exclude: ["CMakeLists.txt"], @@ -181,7 +153,11 @@ var targets: [Target] = [ .target( name: "CompletionScoringTestSupport", - dependencies: ["CompletionScoring", "SwiftExtensions"], + dependencies: [ + "CompletionScoring", + "SwiftExtensions", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), + ], resources: [.copy("INPUTS")], swiftSettings: globalSwiftSettings ), @@ -209,13 +185,14 @@ var targets: [Target] = [ "BuildServerIntegration", "InProcessClient", "LanguageServerProtocolExtensions", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKUtilities", "SourceKitD", "SourceKitLSP", "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", .product(name: "ArgumentParser", package: "swift-argument-parser"), .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), @@ -229,7 +206,7 @@ var targets: [Target] = [ dependencies: [ "BuildServerIntegration", "Diagnose", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKTestSupport", "SourceKitD", "ToolchainRegistry", @@ -244,10 +221,10 @@ var targets: [Target] = [ name: "DocumentationLanguageService", dependencies: [ "BuildServerIntegration", - "BuildServerProtocol", - "LanguageServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "SemanticIndex", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKUtilities", "SourceKitLSP", "SwiftExtensions", @@ -268,86 +245,49 @@ var targets: [Target] = [ "BuildServerIntegration", "ClangLanguageService", "DocumentationLanguageService", - "LanguageServerProtocol", - "SKLogging", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SourceKitLSP", "SwiftLanguageService", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings ), - // MARK: LanguageServerProtocol - - .target( - name: "LanguageServerProtocol", - dependencies: [], - exclude: ["CMakeLists.txt"], - swiftSettings: globalSwiftSettings - ), - - .testTarget( - name: "LanguageServerProtocolTests", - dependencies: [ - "LanguageServerProtocol", - "SKTestSupport", - ], - swiftSettings: globalSwiftSettings - ), - // MARK: LanguageServerProtocolExtensions .target( name: "LanguageServerProtocolExtensions", dependencies: [ - "LanguageServerProtocol", - "LanguageServerProtocolJSONRPC", - "SKLogging", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), + .product(name: "SKLogging", package: "swift-tools-protocols"), "SourceKitD", "SwiftExtensions", .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings ), - // MARK: LanguageServerProtocolJSONRPC - - .target( - name: "LanguageServerProtocolJSONRPC", - dependencies: [ - "LanguageServerProtocol", - "SKLogging", - "SwiftExtensions", - ], - exclude: ["CMakeLists.txt"], - swiftSettings: globalSwiftSettings - ), - - .testTarget( - name: "LanguageServerProtocolJSONRPCTests", - dependencies: [ - "LanguageServerProtocolJSONRPC", - "SKTestSupport", - ], - swiftSettings: globalSwiftSettings - ), - // MARK: SemanticIndex .target( name: "SemanticIndex", dependencies: [ - "BuildServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), "BuildServerIntegration", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", .product(name: "IndexStoreDB", package: "indexstore-db"), ], @@ -359,45 +299,9 @@ var targets: [Target] = [ name: "SemanticIndexTests", dependencies: [ "SemanticIndex", - "SKLogging", - "SKTestSupport", - ], - swiftSettings: globalSwiftSettings - ), - - // MARK: SKLogging - - .target( - name: "SKLogging", - dependencies: [ - "SwiftExtensions", - .product(name: "Crypto", package: "swift-crypto"), - ], - exclude: ["CMakeLists.txt"], - swiftSettings: globalSwiftSettings + lspLoggingSwiftSettings - ), - - .target( - name: "SKLoggingForPlugin", - dependencies: [ - "SwiftExtensionsForPlugin" - ], - exclude: ["CMakeLists.txt"], - swiftSettings: globalSwiftSettings + lspLoggingSwiftSettings + [ - // We can't depend on swift-crypto in the plugin because we can't module-alias it due to https://github.com/swiftlang/swift-package-manager/issues/8119 - .define("NO_CRYPTO_DEPENDENCY"), - .define("SKLOGGING_FOR_PLUGIN"), - .unsafeFlags([ - "-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin", - ]), - ] - ), - - .testTarget( - name: "SKLoggingTests", - dependencies: [ - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKTestSupport", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], swiftSettings: globalSwiftSettings ), @@ -407,9 +311,9 @@ var targets: [Target] = [ .target( name: "SKOptions", dependencies: [ - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), ], exclude: ["CMakeLists.txt"], @@ -421,7 +325,7 @@ var targets: [Target] = [ .target( name: "SKUtilities", dependencies: [ - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SwiftExtensions", ], exclude: ["CMakeLists.txt"], @@ -431,13 +335,13 @@ var targets: [Target] = [ .target( name: "SKUtilitiesForPlugin", dependencies: [ - "SKLoggingForPlugin", + .product(name: "_SKLoggingForPlugin", package: "swift-tools-protocols"), "SwiftExtensionsForPlugin", ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings + [ .unsafeFlags([ - "-module-alias", "SKLogging=SKLoggingForPlugin", + "-module-alias", "SKLogging=_SKLoggingForPlugin", "-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin", ]) ] @@ -461,10 +365,10 @@ var targets: [Target] = [ "CSKTestSupport", "Csourcekitd", "InProcessClient", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", - "SKLogging", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKUtilities", "SourceKitD", @@ -472,6 +376,7 @@ var targets: [Target] = [ "SwiftExtensions", "SwiftLanguageService", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), ], @@ -485,8 +390,9 @@ var targets: [Target] = [ name: "SourceKitD", dependencies: [ "Csourcekitd", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SwiftExtensions", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt", "sourcekitd_uids.swift.gyb"], swiftSettings: globalSwiftSettings @@ -496,13 +402,14 @@ var targets: [Target] = [ name: "SourceKitDForPlugin", dependencies: [ "Csourcekitd", - "SKLoggingForPlugin", + .product(name: "_SKLoggingForPlugin", package: "swift-tools-protocols"), "SwiftExtensionsForPlugin", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt", "sourcekitd_uids.swift.gyb"], swiftSettings: globalSwiftSettings + [ .unsafeFlags([ - "-module-alias", "SKLogging=SKLoggingForPlugin", + "-module-alias", "SKLogging=_SKLoggingForPlugin", "-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin", ]) ] @@ -516,6 +423,7 @@ var targets: [Target] = [ "SKTestSupport", "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], swiftSettings: globalSwiftSettings ), @@ -525,18 +433,19 @@ var targets: [Target] = [ .target( name: "SourceKitLSP", dependencies: [ - "BuildServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), "BuildServerIntegration", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), "SemanticIndex", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKUtilities", "SourceKitD", "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", .product(name: "IndexStoreDB", package: "indexstore-db"), .product(name: "Markdown", package: "swift-markdown"), @@ -548,12 +457,12 @@ var targets: [Target] = [ .testTarget( name: "SourceKitLSPTests", dependencies: [ - "BuildServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), "BuildServerIntegration", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", "SemanticIndex", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKTestSupport", "SKUtilities", @@ -561,6 +470,7 @@ var targets: [Target] = [ "SourceKitLSP", "SwiftLanguageService", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), .product(name: "IndexStoreDB", package: "indexstore-db"), .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), // Depend on `SwiftCompilerPlugin` and `SwiftSyntaxMacros` so the modules are built before running tests and can @@ -576,14 +486,18 @@ var targets: [Target] = [ .target( name: "SwiftExtensions", - dependencies: ["CAtomics"], + dependencies: [ + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols") + ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings ), .target( name: "SwiftExtensionsForPlugin", - dependencies: ["CAtomics"], + dependencies: [ + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols") + ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings ), @@ -591,9 +505,10 @@ var targets: [Target] = [ .testTarget( name: "SwiftExtensionsTests", dependencies: [ - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKTestSupport", "SwiftExtensions", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], swiftSettings: globalSwiftSettings ), @@ -603,20 +518,21 @@ var targets: [Target] = [ .target( name: "SwiftLanguageService", dependencies: [ - "BuildServerProtocol", + .product(name: "BuildServerProtocol", package: "swift-tools-protocols"), "BuildServerIntegration", "Csourcekitd", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "LanguageServerProtocolExtensions", - "LanguageServerProtocolJSONRPC", + .product(name: "LanguageServerProtocolTransport", package: "swift-tools-protocols"), "SemanticIndex", - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKOptions", "SKUtilities", "SourceKitD", "SourceKitLSP", "SwiftExtensions", "ToolchainRegistry", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), "TSCExtensions", .product(name: "IndexStoreDB", package: "indexstore-db"), .product(name: "Crypto", package: "swift-crypto"), @@ -664,14 +580,14 @@ var targets: [Target] = [ "Csourcekitd", "SourceKitDForPlugin", "SwiftExtensionsForPlugin", - "SKLoggingForPlugin", + .product(name: "_SKLoggingForPlugin", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings + [ .unsafeFlags([ "-module-alias", "SourceKitD=SourceKitDForPlugin", "-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin", - "-module-alias", "SKLogging=SKLoggingForPlugin", + "-module-alias", "SKLogging=_SKLoggingForPlugin", ]) ] ), @@ -684,10 +600,11 @@ var targets: [Target] = [ "Csourcekitd", "CompletionScoringForPlugin", "SKUtilitiesForPlugin", - "SKLoggingForPlugin", + .product(name: "_SKLoggingForPlugin", package: "swift-tools-protocols"), "SourceKitDForPlugin", "SwiftSourceKitPluginCommon", "SwiftExtensionsForPlugin", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings + [ @@ -695,7 +612,7 @@ var targets: [Target] = [ "-module-alias", "CompletionScoring=CompletionScoringForPlugin", "-module-alias", "SKUtilities=SKUtilitiesForPlugin", "-module-alias", "SourceKitD=SourceKitDForPlugin", - "-module-alias", "SKLogging=SKLoggingForPlugin", + "-module-alias", "SKLogging=_SKLoggingForPlugin", "-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin", ]) ], @@ -708,7 +625,7 @@ var targets: [Target] = [ "BuildServerIntegration", "CompletionScoring", "Csourcekitd", - "LanguageServerProtocol", + .product(name: "LanguageServerProtocol", package: "swift-tools-protocols"), "SKTestSupport", "SourceKitD", "SwiftExtensions", @@ -722,7 +639,7 @@ var targets: [Target] = [ .target( name: "ToolchainRegistry", dependencies: [ - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SKUtilities", "SwiftExtensions", "TSCExtensions", @@ -745,9 +662,10 @@ var targets: [Target] = [ .target( name: "TSCExtensions", dependencies: [ - "SKLogging", + .product(name: "SKLogging", package: "swift-tools-protocols"), "SwiftExtensions", .product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"), + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], exclude: ["CMakeLists.txt"], swiftSettings: globalSwiftSettings @@ -759,6 +677,7 @@ var targets: [Target] = [ "SKTestSupport", "SwiftExtensions", "TSCExtensions", + .product(name: "ToolsProtocolsSwiftExtensions", package: "swift-tools-protocols"), ], swiftSettings: globalSwiftSettings ), @@ -858,6 +777,7 @@ var dependencies: [Package.Dependency] { .package(path: "../swift-docc"), .package(path: "../swift-docc-symbolkit"), .package(path: "../swift-markdown"), + .package(path: "../swift-tools-protocols"), .package(path: "../swift-tools-support-core"), .package(path: "../swift-argument-parser"), .package(path: "../swift-syntax"), @@ -871,6 +791,7 @@ var dependencies: [Package.Dependency] { .package(url: "https://github.com/swiftlang/swift-docc.git", branch: relatedDependenciesBranch), .package(url: "https://github.com/swiftlang/swift-docc-symbolkit.git", branch: relatedDependenciesBranch), .package(url: "https://github.com/swiftlang/swift-markdown.git", branch: relatedDependenciesBranch), + .package(url: "https://github.com/swiftlang/swift-tools-protocols.git", from: "0.0.2"), .package(url: "https://github.com/swiftlang/swift-tools-support-core.git", branch: relatedDependenciesBranch), .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.5.1"), .package(url: "https://github.com/swiftlang/swift-syntax.git", branch: relatedDependenciesBranch), diff --git a/Sources/BuildServerIntegration/BuildServerHooks.swift b/Sources/BuildServerIntegration/BuildServerHooks.swift index cb2d14d93..cad9437dd 100644 --- a/Sources/BuildServerIntegration/BuildServerHooks.swift +++ b/Sources/BuildServerIntegration/BuildServerHooks.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol package struct SwiftPMTestHooks: Sendable { package var reloadPackageDidStart: (@Sendable () async -> Void)? diff --git a/Sources/BuildServerIntegration/BuildServerManager.swift b/Sources/BuildServerIntegration/BuildServerManager.swift index 8d4f00b87..938399557 100644 --- a/Sources/BuildServerIntegration/BuildServerManager.swift +++ b/Sources/BuildServerIntegration/BuildServerManager.swift @@ -10,17 +10,19 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Dispatch package import Foundation -package import LanguageServerProtocol -package import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging package import SKOptions import SKUtilities -package import SwiftExtensions +import SwiftExtensions import TSCExtensions package import ToolchainRegistry +@_spi(SourceKitLSP) package import ToolsProtocolsSwiftExtensions import struct TSCBasic.RelativePath @@ -1085,7 +1087,7 @@ package actor BuildServerManager: QueueBasedMessageHandler { ) async -> FileBuildSettings? { let buildSettingsFromBuildServer = await orLog("Getting build settings") { if fallbackAfterTimeout { - try await withTimeout(options.buildSettingsTimeoutOrDefault) { + try await SwiftExtensions.withTimeout(options.buildSettingsTimeoutOrDefault) { return try await self.buildSettingsFromBuildServer(for: document, in: target, language: language) } resultReceivedAfterTimeout: { _ in await self.filesBuildSettingsChangedDebouncer.scheduleCall([document]) @@ -1390,7 +1392,7 @@ package actor BuildServerManager: QueueBasedMessageHandler { private func buildTargets() async throws -> [BuildTargetIdentifier: BuildTargetInfo] { let request = WorkspaceBuildTargetsRequest() let result = try await cachedBuildTargets.get(request, isolation: self) { request in - let result = try await withTimeout(self.options.buildServerWorkspaceRequestsTimeoutOrDefault) { + let result = try await SwiftExtensions.withTimeout(self.options.buildServerWorkspaceRequestsTimeoutOrDefault) { guard let buildServerAdapter = try await self.buildServerAdapterAfterInitialized else { return [:] } @@ -1458,7 +1460,7 @@ package actor BuildServerManager: QueueBasedMessageHandler { } let response = try await cachedTargetSources.get(request, isolation: self) { request in - try await withTimeout(self.options.buildServerWorkspaceRequestsTimeoutOrDefault) { + try await SwiftExtensions.withTimeout(self.options.buildServerWorkspaceRequestsTimeoutOrDefault) { guard let buildServerAdapter = try await self.buildServerAdapterAfterInitialized else { return BuildTargetSourcesResponse(items: []) } diff --git a/Sources/BuildServerIntegration/BuildServerManagerDelegate.swift b/Sources/BuildServerIntegration/BuildServerManagerDelegate.swift index 71b78df00..69145c3ec 100644 --- a/Sources/BuildServerIntegration/BuildServerManagerDelegate.swift +++ b/Sources/BuildServerIntegration/BuildServerManagerDelegate.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol /// Handles build server events, such as file build settings changes. package protocol BuildServerManagerDelegate: AnyObject, Sendable { diff --git a/Sources/BuildServerIntegration/BuildServerMessageDependencyTracker.swift b/Sources/BuildServerIntegration/BuildServerMessageDependencyTracker.swift index 1850badce..afe0e424f 100644 --- a/Sources/BuildServerIntegration/BuildServerMessageDependencyTracker.swift +++ b/Sources/BuildServerIntegration/BuildServerMessageDependencyTracker.swift @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -import BuildServerProtocol -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions /// A lightweight way of describing tasks that are created from handling BSP diff --git a/Sources/BuildServerIntegration/BuildSettingsLogger.swift b/Sources/BuildServerIntegration/BuildSettingsLogger.swift index 3d13085d1..9bf888218 100644 --- a/Sources/BuildServerIntegration/BuildSettingsLogger.swift +++ b/Sources/BuildServerIntegration/BuildSettingsLogger.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -package import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) package import SKLogging import SwiftExtensions // MARK: - Build settings logger diff --git a/Sources/BuildServerIntegration/BuildTargetIdentifierExtensions.swift b/Sources/BuildServerIntegration/BuildTargetIdentifierExtensions.swift index d853afb20..5c5138ad0 100644 --- a/Sources/BuildServerIntegration/BuildTargetIdentifierExtensions.swift +++ b/Sources/BuildServerIntegration/BuildTargetIdentifierExtensions.swift @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) public import SKLogging extension BuildTargetIdentifier { package static let dummy: BuildTargetIdentifier = BuildTargetIdentifier(uri: try! URI(string: "dummy://dummy")) @@ -146,7 +146,7 @@ extension BuildTargetIdentifier { } } -extension BuildTargetIdentifier: CustomLogStringConvertible { +@_spi(SourceKitLSP) extension BuildTargetIdentifier: @retroactive CustomLogStringConvertible { package var description: String { return uri.stringValue } diff --git a/Sources/BuildServerIntegration/BuiltInBuildServer.swift b/Sources/BuildServerIntegration/BuiltInBuildServer.swift index 814448e61..c2f766d02 100644 --- a/Sources/BuildServerIntegration/BuiltInBuildServer.swift +++ b/Sources/BuildServerIntegration/BuiltInBuildServer.swift @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol package import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import ToolchainRegistry diff --git a/Sources/BuildServerIntegration/BuiltInBuildServerAdapter.swift b/Sources/BuildServerIntegration/BuiltInBuildServerAdapter.swift index a22396175..3cc3a0718 100644 --- a/Sources/BuildServerIntegration/BuiltInBuildServerAdapter.swift +++ b/Sources/BuildServerIntegration/BuiltInBuildServerAdapter.swift @@ -10,14 +10,16 @@ // //===----------------------------------------------------------------------===// -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol package import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKOptions import SwiftExtensions import ToolchainRegistry +import ToolsProtocolsSwiftExtensions /// The details necessary to create a `BuildServerAdapter`. package struct BuildServerSpec { diff --git a/Sources/BuildServerIntegration/CMakeLists.txt b/Sources/BuildServerIntegration/CMakeLists.txt index 8e4d61f98..b3ab347d4 100644 --- a/Sources/BuildServerIntegration/CMakeLists.txt +++ b/Sources/BuildServerIntegration/CMakeLists.txt @@ -25,14 +25,15 @@ add_library(BuildServerIntegration STATIC set_target_properties(BuildServerIntegration PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(BuildServerIntegration PUBLIC - BuildServerProtocol - LanguageServerProtocol - LanguageServerProtocolJSONRPC - SKLogging + SwiftToolsProtocols::BuildServerProtocol + SwiftToolsProtocols::LanguageServerProtocol + SwiftToolsProtocols::LanguageServerProtocolTransport + SwiftToolsProtocols::SKLogging SKOptions LanguageServerProtocolExtensions SourceKitD SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions ToolchainRegistry PackageModel TSCBasic diff --git a/Sources/BuildServerIntegration/CompilationDatabase.swift b/Sources/BuildServerIntegration/CompilationDatabase.swift index 99bd1314c..77e9f5efe 100644 --- a/Sources/BuildServerIntegration/CompilationDatabase.swift +++ b/Sources/BuildServerIntegration/CompilationDatabase.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// package import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions import TSCExtensions diff --git a/Sources/BuildServerIntegration/DetermineBuildServer.swift b/Sources/BuildServerIntegration/DetermineBuildServer.swift index 9c3d06254..b3878841e 100644 --- a/Sources/BuildServerIntegration/DetermineBuildServer.swift +++ b/Sources/BuildServerIntegration/DetermineBuildServer.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging package import SKOptions import SwiftExtensions import TSCExtensions diff --git a/Sources/BuildServerIntegration/ExternalBuildServerAdapter.swift b/Sources/BuildServerIntegration/ExternalBuildServerAdapter.swift index 3f507f8d8..920a54dd3 100644 --- a/Sources/BuildServerIntegration/ExternalBuildServerAdapter.swift +++ b/Sources/BuildServerIntegration/ExternalBuildServerAdapter.swift @@ -10,12 +10,12 @@ // //===----------------------------------------------------------------------===// -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKOptions import SwiftExtensions import TSCExtensions @@ -182,7 +182,7 @@ actor ExternalBuildServerAdapter { executable: serverPath, arguments: serverArgs, name: "BSP-Server", - protocol: bspRegistry, + protocol: MessageRegistry.bspProtocol, stderrLoggingCategory: "bsp-server-stderr", client: messagesToSourceKitLSPHandler, terminationHandler: { [weak self] terminationReason in diff --git a/Sources/BuildServerIntegration/FallbackBuildSettings.swift b/Sources/BuildServerIntegration/FallbackBuildSettings.swift index 1fcfe3e01..dc0a3b082 100644 --- a/Sources/BuildServerIntegration/FallbackBuildSettings.swift +++ b/Sources/BuildServerIntegration/FallbackBuildSettings.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions package import SKOptions import SwiftExtensions import TSCExtensions diff --git a/Sources/BuildServerIntegration/FileBuildSettings.swift b/Sources/BuildServerIntegration/FileBuildSettings.swift index fab6ef5db..e59f09647 100644 --- a/Sources/BuildServerIntegration/FileBuildSettings.swift +++ b/Sources/BuildServerIntegration/FileBuildSettings.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions /// Build settings for a single file. /// diff --git a/Sources/BuildServerIntegration/FixedCompilationDatabaseBuildServer.swift b/Sources/BuildServerIntegration/FixedCompilationDatabaseBuildServer.swift index 672111a1d..5f4a69d3b 100644 --- a/Sources/BuildServerIntegration/FixedCompilationDatabaseBuildServer.swift +++ b/Sources/BuildServerIntegration/FixedCompilationDatabaseBuildServer.swift @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol package import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions func lastIndexStorePathArgument(in compilerArgs: [String]) -> String? { diff --git a/Sources/BuildServerIntegration/JSONCompilationDatabaseBuildServer.swift b/Sources/BuildServerIntegration/JSONCompilationDatabaseBuildServer.swift index f6e9a619b..766206a84 100644 --- a/Sources/BuildServerIntegration/JSONCompilationDatabaseBuildServer.swift +++ b/Sources/BuildServerIntegration/JSONCompilationDatabaseBuildServer.swift @@ -10,10 +10,10 @@ // //===----------------------------------------------------------------------===// -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol package import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions package import ToolchainRegistry diff --git a/Sources/BuildServerIntegration/LegacyBuildServer.swift b/Sources/BuildServerIntegration/LegacyBuildServer.swift index 2578450e7..69b627a95 100644 --- a/Sources/BuildServerIntegration/LegacyBuildServer.swift +++ b/Sources/BuildServerIntegration/LegacyBuildServer.swift @@ -10,15 +10,16 @@ // //===----------------------------------------------------------------------===// -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKOptions import SwiftExtensions import ToolchainRegistry +import ToolsProtocolsSwiftExtensions #if compiler(>=6.5) #warning("We have had a two year transition period to the pull based build server. Consider removing this build server") diff --git a/Sources/BuildServerIntegration/MainFilesProvider.swift b/Sources/BuildServerIntegration/MainFilesProvider.swift index 48511de81..54435b92a 100644 --- a/Sources/BuildServerIntegration/MainFilesProvider.swift +++ b/Sources/BuildServerIntegration/MainFilesProvider.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol /// A type that can provide the set of main files that include a particular file. package protocol MainFilesProvider: Sendable { diff --git a/Sources/BuildServerIntegration/SwiftPMBuildServer.swift b/Sources/BuildServerIntegration/SwiftPMBuildServer.swift index fcf5e4d81..bc3f10270 100644 --- a/Sources/BuildServerIntegration/SwiftPMBuildServer.swift +++ b/Sources/BuildServerIntegration/SwiftPMBuildServer.swift @@ -13,20 +13,21 @@ #if !NO_SWIFTPM_DEPENDENCY import Basics @preconcurrency import Build -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Dispatch package import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions @preconcurrency import PackageGraph import PackageLoading @preconcurrency import PackageModel -import SKLogging +@_spi(SourceKitLSP) import SKLogging package import SKOptions @preconcurrency package import SPMBuildCore import SourceControl @preconcurrency package import SourceKitLSPAPI import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import TSCExtensions package import ToolchainRegistry @preconcurrency import Workspace diff --git a/Sources/BuildServerProtocol/CMakeLists.txt b/Sources/BuildServerProtocol/CMakeLists.txt deleted file mode 100644 index dba8de99c..000000000 --- a/Sources/BuildServerProtocol/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -add_library(BuildServerProtocol STATIC - Messages.swift - - Messages/BuildShutdownRequest.swift - Messages/BuildTargetPrepareRequest.swift - Messages/BuildTargetSourcesRequest.swift - Messages/InitializeBuildRequest.swift - Messages/OnBuildExitNotification.swift - Messages/OnBuildInitializedNotification.swift - Messages/OnBuildLogMessageNotification.swift - Messages/OnBuildTargetDidChangeNotification.swift - Messages/OnWatchedFilesDidChangeNotification.swift - Messages/RegisterForChangeNotifications.swift - Messages/TaskFinishNotification.swift - Messages/TaskProgressNotification.swift - Messages/TaskStartNotification.swift - Messages/TextDocumentSourceKitOptionsRequest.swift - Messages/WorkspaceBuildTargetsRequest.swift - Messages/WorkspaceWaitForBuildSystemUpdates.swift - - SupportTypes/BuildTarget.swift - SupportTypes/MessageType.swift - SupportTypes/MillisecondsSince1970Date.swift - SupportTypes/StatusCode.swift - SupportTypes/TaskId.swift - SupportTypes/TextDocumentIdentifier.swift) -set_target_properties(BuildServerProtocol PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -target_link_libraries(BuildServerProtocol PRIVATE - LanguageServerProtocol) diff --git a/Sources/BuildServerProtocol/Messages.swift b/Sources/BuildServerProtocol/Messages.swift deleted file mode 100644 index 5a597488d..000000000 --- a/Sources/BuildServerProtocol/Messages.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -private let requestTypes: [_RequestType.Type] = [ - BuildShutdownRequest.self, - BuildTargetPrepareRequest.self, - BuildTargetSourcesRequest.self, - CreateWorkDoneProgressRequest.self, - InitializeBuildRequest.self, - RegisterForChanges.self, - TextDocumentSourceKitOptionsRequest.self, - WorkspaceBuildTargetsRequest.self, - WorkspaceWaitForBuildSystemUpdatesRequest.self, -] - -private let notificationTypes: [NotificationType.Type] = [ - CancelRequestNotification.self, - FileOptionsChangedNotification.self, - OnBuildExitNotification.self, - OnBuildInitializedNotification.self, - OnBuildLogMessageNotification.self, - OnBuildTargetDidChangeNotification.self, - OnWatchedFilesDidChangeNotification.self, - TaskFinishNotification.self, - TaskProgressNotification.self, - TaskStartNotification.self, -] - -public let bspRegistry = MessageRegistry(requests: requestTypes, notifications: notificationTypes) diff --git a/Sources/BuildServerProtocol/Messages/BuildShutdownRequest.swift b/Sources/BuildServerProtocol/Messages/BuildShutdownRequest.swift deleted file mode 100644 index b9d0a252e..000000000 --- a/Sources/BuildServerProtocol/Messages/BuildShutdownRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Like the language server protocol, the shutdown build request is -/// sent from the client to the server. It asks the server to shut down, -/// but to not exit (otherwise the response might not be delivered -/// correctly to the client). There is a separate exit notification -/// that asks the server to exit. -public struct BuildShutdownRequest: RequestType { - public static let method: String = "build/shutdown" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/BuildServerProtocol/Messages/BuildTargetPrepareRequest.swift b/Sources/BuildServerProtocol/Messages/BuildTargetPrepareRequest.swift deleted file mode 100644 index b0fa54648..000000000 --- a/Sources/BuildServerProtocol/Messages/BuildTargetPrepareRequest.swift +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -public typealias OriginId = String - -/// The prepare build target request is sent from the client to the server to prepare the given list of build targets -/// for editor functionality. -/// -/// To do so, the build server should perform any work that is necessary to typecheck the files in the given target. -/// This includes, but is not limited to: Building Swift modules for all dependencies and running code generation scripts. -/// Compared to a full build, the build server may skip actions that are not necessary for type checking, such as object -/// file generation but the exact steps necessary are dependent on the build system. SwiftPM implements this step using -/// the `swift build --experimental-prepare-for-indexing` command. -/// -/// The server communicates during the initialize handshake whether this method is supported or not by setting -/// `prepareProvider: true` in `SourceKitInitializeBuildResponseData`. -public struct BuildTargetPrepareRequest: RequestType, Hashable { - public static let method: String = "buildTarget/prepare" - public typealias Response = VoidResponse - - /// A list of build targets to prepare. - public var targets: [BuildTargetIdentifier] - - /// A unique identifier generated by the client to identify this request. - /// The server may include this id in triggered notifications or responses. - public var originId: OriginId? - - public init(targets: [BuildTargetIdentifier], originId: OriginId? = nil) { - self.targets = targets - self.originId = originId - } -} diff --git a/Sources/BuildServerProtocol/Messages/BuildTargetSourcesRequest.swift b/Sources/BuildServerProtocol/Messages/BuildTargetSourcesRequest.swift deleted file mode 100644 index ec3722b9f..000000000 --- a/Sources/BuildServerProtocol/Messages/BuildTargetSourcesRequest.swift +++ /dev/null @@ -1,219 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The build target sources request is sent from the client to the server to -/// query for the list of text documents and directories that belong to a -/// build target. The sources response must not include sources that are -/// external to the workspace. -public struct BuildTargetSourcesRequest: RequestType, Hashable { - public static let method: String = "buildTarget/sources" - public typealias Response = BuildTargetSourcesResponse - - public var targets: [BuildTargetIdentifier] - - public init(targets: [BuildTargetIdentifier]) { - self.targets = targets - } -} - -public struct BuildTargetSourcesResponse: ResponseType, Hashable { - public var items: [SourcesItem] - - public init(items: [SourcesItem]) { - self.items = items - } -} - -public struct SourcesItem: Codable, Hashable, Sendable { - public var target: BuildTargetIdentifier - - /// The text documents and directories that belong to this build target. - public var sources: [SourceItem] - - /// The root directories from where source files should be relativized. - /// Example: ["file://Users/name/dev/metals/src/main/scala"] - public var roots: [URI]? - - public init(target: BuildTargetIdentifier, sources: [SourceItem], roots: [URI]? = nil) { - self.target = target - self.sources = sources - self.roots = roots - } -} - -public struct SourceItem: Codable, Hashable, Sendable { - /// Either a text document or a directory. A directory entry must end with a - /// forward slash "/" and a directory entry implies that every nested text - /// document within the directory belongs to this source item. - public var uri: URI - - /// Type of file of the source item, such as whether it is file or directory. - public var kind: SourceItemKind - - /// Indicates if this source is automatically generated by the build and is - /// not intended to be manually edited by the user. - public var generated: Bool - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: SourceItemDataKind? - - /// Language-specific metadata about this source item. - public var data: LSPAny? - - /// If `dataKind` is `sourceKit`, the `data` interpreted as `SourceKitSourceItemData`, otherwise `nil`. - public var sourceKitData: SourceKitSourceItemData? { - guard dataKind == .sourceKit else { - return nil - } - return SourceKitSourceItemData(fromLSPAny: data) - } - - public init( - uri: URI, - kind: SourceItemKind, - generated: Bool, - dataKind: SourceItemDataKind? = nil, - data: LSPAny? = nil - ) { - self.uri = uri - self.kind = kind - self.generated = generated - self.dataKind = dataKind - self.data = data - } -} - -public enum SourceItemKind: Int, Codable, Hashable, Sendable { - /// The source item references a normal file. - case file = 1 - - /// The source item references a directory. - case directory = 2 -} - -public struct SourceItemDataKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// `data` field must contain a JvmSourceItemData object. - public static let jvm = SourceItemDataKind(rawValue: "jvm") - - /// `data` field must contain a `SourceKitSourceItemData` object. - /// - /// **(BSP Extension)** - public static let sourceKit = SourceItemDataKind(rawValue: "sourceKit") -} - -/// **(BSP Extension)** - -public enum SourceKitSourceItemKind: String, Codable { - /// A source file that belongs to the target - case source = "source" - - /// A header file that is clearly associated with one target. - /// - /// For example header files in SwiftPM projects are always associated to one target and SwiftPM can provide build - /// settings for that header file. - /// - /// In general, build servers don't need to list all header files in the `buildTarget/sources` request: Semantic - /// functionality for header files is usually provided by finding a main file that includes the header file and - /// inferring build settings from it. Listing header files in `buildTarget/sources` allows SourceKit-LSP to provide - /// semantic functionality for header files if they haven't been included by any main file. - case header = "header" - - /// A SwiftDocC documentation catalog usually ending in the ".docc" extension. - case doccCatalog = "doccCatalog" -} - -public struct SourceKitSourceItemData: LSPAnyCodable, Codable { - /// The language of the source file. If `nil`, the language is inferred from the file extension. - public var language: Language? - - /// The kind of source file that this source item represents. If omitted, the item is assumed to be a normal source file, - /// ie. omitting this key is equivalent to specifying it as `source`. - public var kind: SourceKitSourceItemKind? - - /// The output path that is used during indexing for this file, ie. the `-index-unit-output-path`, if it is specified - /// in the compiler arguments or the file that is passed as `-o`, if `-index-unit-output-path` is not specified. - /// - /// This allows SourceKit-LSP to remove index entries for source files that are removed from a target but remain - /// present on disk. - /// - /// The server communicates during the initialize handshake whether it populates this property by setting - /// `outputPathsProvider: true` in `SourceKitInitializeBuildResponseData`. - public var outputPath: String? - - /// If this source item gets copied to a different destination during preparation, the destinations it will be copied - /// to. - /// - /// If a user action would jump to one of these copied files, this allows SourceKit-LSP to redirect the navigation to - /// the original source file instead of jumping to a file in the build directory. - public var copyDestinations: [DocumentURI]? - - public init( - language: Language? = nil, - kind: SourceKitSourceItemKind? = nil, - outputPath: String? = nil, - copyDestinations: [DocumentURI]? = nil - ) { - self.language = language - self.kind = kind - self.outputPath = outputPath - self.copyDestinations = copyDestinations - } - - public init?(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) { - if case .string(let language) = dictionary[CodingKeys.language.stringValue] { - self.language = Language(rawValue: language) - } - if case .string(let rawKind) = dictionary[CodingKeys.kind.stringValue] { - self.kind = SourceKitSourceItemKind(rawValue: rawKind) - } - // Backwards compatibility for isHeader - if case .bool(let isHeader) = dictionary["isHeader"], isHeader { - self.kind = .header - } - if case .string(let outputFilePath) = dictionary[CodingKeys.outputPath.stringValue] { - self.outputPath = outputFilePath - } - if case .array(let copyDestinations) = dictionary[CodingKeys.copyDestinations.stringValue] { - self.copyDestinations = copyDestinations.compactMap { entry in - guard case .string(let copyDestination) = entry else { - return nil - } - return try? DocumentURI(string: copyDestination) - } - } - } - - public func encodeToLSPAny() -> LanguageServerProtocol.LSPAny { - var result: [String: LSPAny] = [:] - if let language { - result[CodingKeys.language.stringValue] = .string(language.rawValue) - } - if let kind { - result[CodingKeys.kind.stringValue] = .string(kind.rawValue) - } - if let outputPath { - result[CodingKeys.outputPath.stringValue] = .string(outputPath) - } - if let copyDestinations { - result[CodingKeys.copyDestinations.stringValue] = .array(copyDestinations.map { .string($0.stringValue) }) - } - return .dictionary(result) - } -} diff --git a/Sources/BuildServerProtocol/Messages/InitializeBuildRequest.swift b/Sources/BuildServerProtocol/Messages/InitializeBuildRequest.swift deleted file mode 100644 index 15c720d70..000000000 --- a/Sources/BuildServerProtocol/Messages/InitializeBuildRequest.swift +++ /dev/null @@ -1,359 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Like the language server protocol, the initialize request is sent -/// as the first request from the client to the server. If the server -/// receives a request or notification before the initialize request -/// it should act as follows: -/// -/// - For a request the response should be an error with code: -32002. -/// The message can be picked by the server. -/// -/// - Notifications should be dropped, except for the exit notification. -/// This will allow the exit of a server without an initialize request. -/// -/// Until the server has responded to the initialize request with an -/// InitializeBuildResult, the client must not send any additional -/// requests or notifications to the server. -public struct InitializeBuildRequest: RequestType, Hashable { - public static let method: String = "build/initialize" - public typealias Response = InitializeBuildResponse - - /// Name of the client - public var displayName: String - - /// The version of the client - public var version: String - - /// The BSP version that the client speaks= - public var bspVersion: String - - /// The rootUri of the workspace - public var rootUri: URI - - /// The capabilities of the client - public var capabilities: BuildClientCapabilities - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */ - public var dataKind: InitializeBuildRequestDataKind? - - /// Additional metadata about the client - public var data: LSPAny? - - public init( - displayName: String, - version: String, - bspVersion: String, - rootUri: URI, - capabilities: BuildClientCapabilities, - dataKind: InitializeBuildRequestDataKind? = nil, - data: LSPAny? = nil - ) { - self.displayName = displayName - self.version = version - self.bspVersion = bspVersion - self.rootUri = rootUri - self.capabilities = capabilities - self.dataKind = dataKind - self.data = data - } -} - -public struct BuildClientCapabilities: Codable, Hashable, Sendable { - /// The languages that this client supports. - /// The ID strings for each language is defined in the LSP. - /// The server must never respond with build targets for other - /// languages than those that appear in this list. - public var languageIds: [Language] - - /// Mirror capability to BuildServerCapabilities.jvmCompileClasspathProvider - /// The client will request classpath via `buildTarget/jvmCompileClasspath` so - /// it's safe to return classpath in ScalacOptionsItem empty. */ - public var jvmCompileClasspathReceiver: Bool? - - public init(languageIds: [Language], jvmCompileClasspathReceiver: Bool? = nil) { - self.languageIds = languageIds - self.jvmCompileClasspathReceiver = jvmCompileClasspathReceiver - } -} - -public struct InitializeBuildRequestDataKind: RawRepresentable, Hashable, Codable, Sendable { - public let rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } -} - -public struct InitializeBuildResponse: ResponseType, Hashable { - /// Name of the server - public var displayName: String - - /// The version of the server - public var version: String - - /// The BSP version that the server speaks - public var bspVersion: String - - /// The capabilities of the build server - public var capabilities: BuildServerCapabilities - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: InitializeBuildResponseDataKind? - - /// Optional metadata about the server - public var data: LSPAny? - - public init( - displayName: String, - version: String, - bspVersion: String, - capabilities: BuildServerCapabilities, - dataKind: InitializeBuildResponseDataKind? = nil, - data: LSPAny? = nil - ) { - self.displayName = displayName - self.version = version - self.bspVersion = bspVersion - self.capabilities = capabilities - self.dataKind = dataKind - self.data = data - } -} - -public struct BuildServerCapabilities: Codable, Hashable, Sendable { - /// The languages the server supports compilation via method buildTarget/compile. - public var compileProvider: CompileProvider? - - /// The languages the server supports test execution via method buildTarget/test - public var testProvider: TestProvider? - - /// The languages the server supports run via method buildTarget/run - public var runProvider: RunProvider? - - /// The languages the server supports debugging via method debugSession/start. - public var debugProvider: DebugProvider? - - /// The server can provide a list of targets that contain a - /// single text document via the method buildTarget/inverseSources - public var inverseSourcesProvider: Bool? - - /// The server provides sources for library dependencies - /// via method buildTarget/dependencySources - public var dependencySourcesProvider: Bool? - - /// The server provides all the resource dependencies - /// via method buildTarget/resources - public var resourcesProvider: Bool? - - /// The server provides all output paths - /// via method buildTarget/outputPaths - public var outputPathsProvider: Bool? - - /// The server sends notifications to the client on build - /// target change events via `buildTarget/didChange` - public var buildTargetChangedProvider: Bool? - - /// The server can respond to `buildTarget/jvmRunEnvironment` requests with the - /// necessary information required to launch a Java process to run a main class. - public var jvmRunEnvironmentProvider: Bool? - - /// The server can respond to `buildTarget/jvmTestEnvironment` requests with the - /// necessary information required to launch a Java process for testing or - /// debugging. - public var jvmTestEnvironmentProvider: Bool? - - /// The server can respond to `workspace/cargoFeaturesState` and - /// `setCargoFeatures` requests. In other words, supports Cargo Features extension. - public var cargoFeaturesProvider: Bool? - - /// Reloading the build state through workspace/reload is supported - public var canReload: Bool? - - /// The server can respond to `buildTarget/jvmCompileClasspath` requests with the - /// necessary information about the target's classpath. - public var jvmCompileClasspathProvider: Bool? - - public init( - compileProvider: CompileProvider? = nil, - testProvider: TestProvider? = nil, - runProvider: RunProvider? = nil, - debugProvider: DebugProvider? = nil, - inverseSourcesProvider: Bool? = nil, - dependencySourcesProvider: Bool? = nil, - resourcesProvider: Bool? = nil, - outputPathsProvider: Bool? = nil, - buildTargetChangedProvider: Bool? = nil, - jvmRunEnvironmentProvider: Bool? = nil, - jvmTestEnvironmentProvider: Bool? = nil, - cargoFeaturesProvider: Bool? = nil, - canReload: Bool? = nil, - jvmCompileClasspathProvider: Bool? = nil - ) { - self.compileProvider = compileProvider - self.testProvider = testProvider - self.runProvider = runProvider - self.debugProvider = debugProvider - self.inverseSourcesProvider = inverseSourcesProvider - self.dependencySourcesProvider = dependencySourcesProvider - self.resourcesProvider = resourcesProvider - self.outputPathsProvider = outputPathsProvider - self.buildTargetChangedProvider = buildTargetChangedProvider - self.jvmRunEnvironmentProvider = jvmRunEnvironmentProvider - self.jvmTestEnvironmentProvider = jvmTestEnvironmentProvider - self.cargoFeaturesProvider = cargoFeaturesProvider - self.canReload = canReload - self.jvmCompileClasspathProvider = jvmCompileClasspathProvider - } -} - -public struct CompileProvider: Codable, Hashable, Sendable { - public var languageIds: [Language] - - public init(languageIds: [Language]) { - self.languageIds = languageIds - } -} - -public struct TestProvider: Codable, Hashable, Sendable { - public var languageIds: [Language] - - public init(languageIds: [Language]) { - self.languageIds = languageIds - } -} - -public struct RunProvider: Codable, Hashable, Sendable { - public var languageIds: [Language] - - public init(languageIds: [Language]) { - self.languageIds = languageIds - } -} - -public struct DebugProvider: Codable, Hashable, Sendable { - public var languageIds: [Language] - - public init(languageIds: [Language]) { - self.languageIds = languageIds - } -} - -public struct InitializeBuildResponseDataKind: RawRepresentable, Hashable, Codable, Sendable { - public let rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// `data` field must contain a `SourceKitInitializeBuildResponseData` object. - public static let sourceKit = InitializeBuildResponseDataKind(rawValue: "sourceKit") -} - -public struct SourceKitInitializeBuildResponseData: LSPAnyCodable, Codable, Sendable { - /// The directory to which the index store is written during compilation, ie. the path passed to `-index-store-path` - /// for `swiftc` or `clang` invocations - public var indexDatabasePath: String? - - /// The path at which SourceKit-LSP can store its index database, aggregating data from `indexStorePath` - public var indexStorePath: String? - - /// Whether the server implements the `buildTarget/outputPaths` request. - public var outputPathsProvider: Bool? - - /// Whether the build server supports the `buildTarget/prepare` request. - public var prepareProvider: Bool? - - /// Whether the server implements the `textDocument/sourceKitOptions` request. - public var sourceKitOptionsProvider: Bool? - - /// The files to watch for changes. - public var watchers: [FileSystemWatcher]? - - @available(*, deprecated, message: "Use initializer with alphabetical order of parameters") - @_disfavoredOverload - public init( - indexDatabasePath: String? = nil, - indexStorePath: String? = nil, - watchers: [FileSystemWatcher]? = nil, - prepareProvider: Bool? = nil, - sourceKitOptionsProvider: Bool? = nil - ) { - self.indexDatabasePath = indexDatabasePath - self.indexStorePath = indexStorePath - self.watchers = watchers - self.prepareProvider = prepareProvider - self.sourceKitOptionsProvider = sourceKitOptionsProvider - } - - public init( - indexDatabasePath: String? = nil, - indexStorePath: String? = nil, - outputPathsProvider: Bool? = nil, - prepareProvider: Bool? = nil, - sourceKitOptionsProvider: Bool? = nil, - watchers: [FileSystemWatcher]? = nil - ) { - self.indexDatabasePath = indexDatabasePath - self.indexStorePath = indexStorePath - self.outputPathsProvider = outputPathsProvider - self.prepareProvider = prepareProvider - self.sourceKitOptionsProvider = sourceKitOptionsProvider - self.watchers = watchers - } - - public init?(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) { - if case .string(let indexDatabasePath) = dictionary[CodingKeys.indexDatabasePath.stringValue] { - self.indexDatabasePath = indexDatabasePath - } - if case .string(let indexStorePath) = dictionary[CodingKeys.indexStorePath.stringValue] { - self.indexStorePath = indexStorePath - } - if case .bool(let outputPathsProvider) = dictionary[CodingKeys.outputPathsProvider.stringValue] { - self.outputPathsProvider = outputPathsProvider - } - if case .bool(let prepareProvider) = dictionary[CodingKeys.prepareProvider.stringValue] { - self.prepareProvider = prepareProvider - } - if case .bool(let sourceKitOptionsProvider) = dictionary[CodingKeys.sourceKitOptionsProvider.stringValue] { - self.sourceKitOptionsProvider = sourceKitOptionsProvider - } - if let watchers = dictionary[CodingKeys.watchers.stringValue] { - self.watchers = [FileSystemWatcher](fromLSPArray: watchers) - } - } - - public func encodeToLSPAny() -> LanguageServerProtocol.LSPAny { - var result: [String: LSPAny] = [:] - if let indexDatabasePath { - result[CodingKeys.indexDatabasePath.stringValue] = .string(indexDatabasePath) - } - if let indexStorePath { - result[CodingKeys.indexStorePath.stringValue] = .string(indexStorePath) - } - if let outputPathsProvider { - result[CodingKeys.outputPathsProvider.stringValue] = .bool(outputPathsProvider) - } - if let prepareProvider { - result[CodingKeys.prepareProvider.stringValue] = .bool(prepareProvider) - } - if let sourceKitOptionsProvider { - result[CodingKeys.sourceKitOptionsProvider.stringValue] = .bool(sourceKitOptionsProvider) - } - if let watchers { - result[CodingKeys.watchers.stringValue] = watchers.encodeToLSPAny() - } - return .dictionary(result) - } -} diff --git a/Sources/BuildServerProtocol/Messages/OnBuildExitNotification.swift b/Sources/BuildServerProtocol/Messages/OnBuildExitNotification.swift deleted file mode 100644 index 3c3a66f17..000000000 --- a/Sources/BuildServerProtocol/Messages/OnBuildExitNotification.swift +++ /dev/null @@ -1,23 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Like the language server protocol, a notification to ask the -/// server to exit its process. The server should exit with success -/// code 0 if the shutdown request has been received before; -/// otherwise with error code 1. -public struct OnBuildExitNotification: NotificationType { - public static let method: String = "build/exit" - - public init() {} -} diff --git a/Sources/BuildServerProtocol/Messages/OnBuildInitializedNotification.swift b/Sources/BuildServerProtocol/Messages/OnBuildInitializedNotification.swift deleted file mode 100644 index f1a1e26a3..000000000 --- a/Sources/BuildServerProtocol/Messages/OnBuildInitializedNotification.swift +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Like the language server protocol, the initialized notification is sent from the client to the server after the client received the result of the initialize request but before the client is sending any other request or notification to the server. The server can use the initialized notification for example to initialize intensive computation such as dependency resolution or compilation. The initialized notification may only be sent once. -public struct OnBuildInitializedNotification: NotificationType { - public static let method: String = "build/initialized" - - public init() {} -} diff --git a/Sources/BuildServerProtocol/Messages/OnBuildLogMessageNotification.swift b/Sources/BuildServerProtocol/Messages/OnBuildLogMessageNotification.swift deleted file mode 100644 index b9b5bd5dd..000000000 --- a/Sources/BuildServerProtocol/Messages/OnBuildLogMessageNotification.swift +++ /dev/null @@ -1,174 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The log message notification is sent from a server to a client to ask the client to log a particular message in its console. -/// -/// A `build/logMessage`` notification is similar to LSP's `window/logMessage``, except for a few additions like id and originId. -public struct OnBuildLogMessageNotification: NotificationType { - public static let method: String = "build/logMessage" - - /// The message type. - public var type: MessageType - - /// The task id if any. - public var task: TaskId? - - /// The request id that originated this notification. - /// The originId field helps clients know which request originated a notification in case several requests are handled by the - /// client at the same time. It will only be populated if the client defined it in the request that triggered this notification. - public var originId: OriginId? - - /// The actual message. - public var message: String - - /// Extends BSPs log message grouping by explicitly starting and ending the log for a specific task ID. - /// - /// **(BSP Extension)*** - public var structure: StructuredLogKind? - - public init( - type: MessageType, - task: TaskId? = nil, - originId: OriginId? = nil, - message: String, - structure: StructuredLogKind? = nil - ) { - self.type = type - self.task = task - self.originId = originId - self.message = message - self.structure = structure - } -} - -public enum StructuredLogKind: Codable, Hashable, Sendable { - case begin(StructuredLogBegin) - case report(StructuredLogReport) - case end(StructuredLogEnd) - - public init(from decoder: Decoder) throws { - if let begin = try? StructuredLogBegin(from: decoder) { - self = .begin(begin) - } else if let report = try? StructuredLogReport(from: decoder) { - self = .report(report) - } else if let end = try? StructuredLogEnd(from: decoder) { - self = .end(end) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected StructuredLogBegin, StructuredLogReport, or StructuredLogEnd" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .begin(let begin): - try begin.encode(to: encoder) - case .report(let report): - try report.encode(to: encoder) - case .end(let end): - try end.encode(to: encoder) - } - } -} - -/// Indicates the beginning of a new task that may receive updates with `StructuredLogReport` or `StructuredLogEnd` -/// payloads. -public struct StructuredLogBegin: Codable, Hashable, Sendable { - /// A succinct title that can be used to describe the task that started this structured. - public var title: String - - private enum CodingKeys: CodingKey { - case kind - case title - } - - public init(title: String) { - self.title = title - } - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "begin" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogBegin is not 'begin'" - ) - } - - self.title = try container.decode(String.self, forKey: .title) - - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("begin", forKey: .kind) - try container.encode(self.title, forKey: .title) - } -} - -/// Adds a new log message to a structured log without ending it. -public struct StructuredLogReport: Codable, Hashable, Sendable { - private enum CodingKeys: CodingKey { - case kind - } - - public init() {} - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "report" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogReport is not 'report'" - ) - } - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("report", forKey: .kind) - } -} - -/// Ends a structured log. No more `StructuredLogReport` updates should be sent for this task ID. -/// -/// The task ID may be re-used for new structured logs by beginning a new structured log for that task. -public struct StructuredLogEnd: Codable, Hashable, Sendable { - private enum CodingKeys: CodingKey { - case kind - } - - public init() {} - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "end" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogEnd is not 'end'" - ) - } - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("end", forKey: .kind) - } -} diff --git a/Sources/BuildServerProtocol/Messages/OnBuildTargetDidChangeNotification.swift b/Sources/BuildServerProtocol/Messages/OnBuildTargetDidChangeNotification.swift deleted file mode 100644 index 592d78b92..000000000 --- a/Sources/BuildServerProtocol/Messages/OnBuildTargetDidChangeNotification.swift +++ /dev/null @@ -1,73 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The build target changed notification is sent from the server to the client -/// to signal a change in a build target. The server communicates during the -/// initialize handshake whether this method is supported or not. -public struct OnBuildTargetDidChangeNotification: NotificationType, Equatable { - public static let method: String = "buildTarget/didChange" - - /// **(BSP Extension)** - /// `changes` can be `nil` to indicate that all targets might have changed. - public var changes: [BuildTargetEvent]? - - public init(changes: [BuildTargetEvent]?) { - self.changes = changes - } -} - -public struct BuildTargetEvent: Codable, Hashable, Sendable { - /// The identifier for the changed build target. - public var target: BuildTargetIdentifier - - /// The kind of change for this build target. - public var kind: BuildTargetEventKind? - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: BuildTargetEventDataKind? - - /// Any additional metadata about what information changed. - public var data: LSPAny? - - public init( - target: BuildTargetIdentifier, - kind: BuildTargetEventKind?, - dataKind: BuildTargetEventDataKind?, - data: LSPAny? - ) { - self.target = target - self.kind = kind - self.dataKind = dataKind - self.data = data - } -} - -public enum BuildTargetEventKind: Int, Codable, Hashable, Sendable { - /// The build target is new. - case created = 1 - - /// The build target has changed. - case changed = 2 - - /// The build target has been deleted. - case deleted = 3 -} - -public struct BuildTargetEventDataKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } -} diff --git a/Sources/BuildServerProtocol/Messages/OnWatchedFilesDidChangeNotification.swift b/Sources/BuildServerProtocol/Messages/OnWatchedFilesDidChangeNotification.swift deleted file mode 100644 index 656cf109f..000000000 --- a/Sources/BuildServerProtocol/Messages/OnWatchedFilesDidChangeNotification.swift +++ /dev/null @@ -1,16 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Notification sent from SourceKit-LSP to the build server to indicate that files within the project have been modified. -public typealias OnWatchedFilesDidChangeNotification = LanguageServerProtocol.DidChangeWatchedFilesNotification diff --git a/Sources/BuildServerProtocol/Messages/RegisterForChangeNotifications.swift b/Sources/BuildServerProtocol/Messages/RegisterForChangeNotifications.swift deleted file mode 100644 index 1b408397a..000000000 --- a/Sources/BuildServerProtocol/Messages/RegisterForChangeNotifications.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The register for changes request is sent from the language -/// server to the build server to register or unregister for -/// changes in file options or dependencies. On changes a -/// FileOptionsChangedNotification is sent. -/// -/// - Important: This request has been deprecated. Build servers should instead implement the -/// `textDocument/sourceKitOptions` request. -/// See https://forums.swift.org/t/extending-functionality-of-build-server-protocol-with-sourcekit-lsp/74400 -public struct RegisterForChanges: RequestType { - public static let method: String = "textDocument/registerForChanges" - public typealias Response = VoidResponse - - /// The URI of the document to get options for. - public var uri: URI - - /// Whether to register or unregister for the file. - public var action: RegisterAction - - public init(uri: URI, action: RegisterAction) { - self.uri = uri - self.action = action - } -} - -public enum RegisterAction: String, Hashable, Codable, Sendable { - case register = "register" - case unregister = "unregister" -} - -/// The FileOptionsChangedNotification is sent from the -/// build server to the language server when it detects -/// changes to a registered files build settings. -/// -/// - Important: This request has been deprecated. Build servers should instead implement the -/// `textDocument/sourceKitOptions` request. -/// See https://forums.swift.org/t/extending-functionality-of-build-server-protocol-with-sourcekit-lsp/74400 -public struct FileOptionsChangedNotification: NotificationType { - public struct Options: ResponseType, Hashable { - /// The compiler options required for the requested file. - public var options: [String] - - /// The working directory for the compile command. - public var workingDirectory: String? - } - - public static let method: String = "build/sourceKitOptionsChanged" - - /// The URI of the document that has changed settings. - public var uri: URI - - /// The updated options for the registered file. - public var updatedOptions: Options -} diff --git a/Sources/BuildServerProtocol/Messages/TaskFinishNotification.swift b/Sources/BuildServerProtocol/Messages/TaskFinishNotification.swift deleted file mode 100644 index 4bcb54f21..000000000 --- a/Sources/BuildServerProtocol/Messages/TaskFinishNotification.swift +++ /dev/null @@ -1,240 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation -public import LanguageServerProtocol - -/// A `build/taskFinish` notification must always be sent after a `build/taskStart`` with the same `taskId` was sent. -public struct TaskFinishNotification: NotificationType { - public static let method: String = "build/taskFinish" - - /// Unique id of the task with optional reference to parent task id. - public var taskId: TaskId - - /// A unique identifier generated by the client to identify this request. - public var originId: String? - - /// Timestamp of when the event started in milliseconds since Epoch. - @CustomCodable - public var eventTime: Date? - - /// Message describing the task. - public var message: String? - - /// Task completion status. - public var status: StatusCode - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: TaskFinishDataKind? - - /// Optional metadata about the task. - /// - /// Objects for specific tasks like compile, test, etc are specified in the protocol. - public var data: LSPAny? - - public init( - taskId: TaskId, - originId: String? = nil, - eventTime: Date? = nil, - message: String? = nil, - status: StatusCode, - dataKind: TaskFinishDataKind? = nil, - data: LSPAny? = nil - ) { - self.taskId = taskId - self.originId = originId - self.eventTime = eventTime - self.message = message - self.status = status - self.dataKind = dataKind - self.data = data - } - -} - -/// Task finish notifications may contain an arbitrary interface in their `data` field. -/// -/// The kind of interface that is contained in a notification must be specified in the `dataKind` field. -public struct TaskFinishDataKind: RawRepresentable, Codable, Hashable, Sendable { - public let rawValue: String - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// `data` field must contain a `CompileReport` object. - public static let compileReport = TaskStartDataKind(rawValue: "compile-report") - - /// `data` field must contain a `TestFinish` object. - public static let testFinish = TaskStartDataKind(rawValue: "test-finish") - - /// `data` field must contain a `TestReport` object. - public static let testReport = TaskStartDataKind(rawValue: "test-report") -} - -/// This structure is embedded in the `TaskFinishNotification.data` field, when the `dataKind` field contains -/// `"compile-report"`. -/// -/// The completion of a compilation task should be signalled with a `build/taskFinish` notification. When the -/// compilation unit is a build target, the notification's `dataKind` field must be `compile-report` and the `data` -/// field must include a `CompileReportData` object. -public struct CompileReportData: Codable, Hashable, Sendable { - /// The build target that was compiled. - public var target: BuildTargetIdentifier - - /// An optional request id to know the origin of this report. - /// - /// Deprecated: Use the field in TaskFinishParams instead . - public var originId: String? - - /// The total number of reported errors compiling this target. - public var errors: Int - - /// The total number of reported warnings compiling the target. - public var warnings: Int - - /// The total number of milliseconds it took to compile the target. - @CustomCodable - public var time: Date? - - /// The compilation was a noOp compilation. - public var noOp: Bool? - - public init( - target: BuildTargetIdentifier, - originId: String? = nil, - errors: Int, - warnings: Int, - time: Date? = nil, - noOp: Bool? = nil - ) { - self.target = target - self.originId = originId - self.errors = errors - self.warnings = warnings - self.time = time - self.noOp = noOp - } -} - -/// This structure is embedded in the `TaskFinishNotification.data` field, when the `dataKind` field contains -/// `"test-finish"`. -public struct TestFinishData: Codable, Hashable, Sendable { - /// Name or description of the test. - public var displayName: String? - - /// Information about completion of the test, for example an error message. - public var message: String? - - /// Completion status of the test. - public var status: TestStatus - - /// Source location of the test, as LSP location. - public var location: Location? - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: TestFinishDataKind? - - /// Optionally, structured metadata about the test completion. - /// For example: stack traces, expected/actual values. - public var data: LSPAny? - - public init( - displayName: String? = nil, - message: String? = nil, - status: TestStatus, - location: Location? = nil, - dataKind: TestFinishDataKind? = nil, - data: LSPAny? = nil - ) { - self.displayName = displayName - self.message = message - self.status = status - self.location = location - self.dataKind = dataKind - self.data = data - } - -} - -public enum TestStatus: Int, Codable, Hashable, Sendable { - /// The test passed successfully. - case passed = 1 - - /// The test failed. - case failed = 2 - - /// The test was marked as ignored. - case ignored = 3 - - /// The test execution was cancelled. - case cancelled = 4 - - /// The was not included in execution. - case skipped = 5 -} - -public struct TestFinishDataKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init?(rawValue: String) { - self.rawValue = rawValue - } -} - -/// This structure is embedded in the `TaskFinishNotification.data` field, when the `dataKind` field contains -/// `"test-report"`. -public struct TestReportData: Codable, Hashable, Sendable { - /// Deprecated: Use the field in TaskFinishParams instead - public var originId: String? - - /// The build target that was compiled. - public var target: BuildTargetIdentifier - - /// The total number of successful tests. - public var passed: Int - - /// The total number of failed tests. - public var failed: Int - - /// The total number of ignored tests. - public var ignored: Int - - /// The total number of cancelled tests. - public var cancelled: Int - - /// The total number of skipped tests. - public var skipped: Int - - /// The total number of milliseconds tests take to run (e.g. doesn't include compile times). - public var time: Int64? - - public init( - originId: String? = nil, - target: BuildTargetIdentifier, - passed: Int, - failed: Int, - ignored: Int, - cancelled: Int, - skipped: Int, - time: Int64? = nil - ) { - self.originId = originId - self.target = target - self.passed = passed - self.failed = failed - self.ignored = ignored - self.cancelled = cancelled - self.skipped = skipped - self.time = time - } - -} diff --git a/Sources/BuildServerProtocol/Messages/TaskProgressNotification.swift b/Sources/BuildServerProtocol/Messages/TaskProgressNotification.swift deleted file mode 100644 index d4cfd3dc7..000000000 --- a/Sources/BuildServerProtocol/Messages/TaskProgressNotification.swift +++ /dev/null @@ -1,82 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation -public import LanguageServerProtocol - -/// After a `taskStart` and before `taskFinish` for a `taskId`, the server may send any number of progress -/// notifications. -public struct TaskProgressNotification: NotificationType { - public static let method: String = "build/taskProgress" - - /// Unique id of the task with optional reference to parent task id - public var taskId: TaskId - - /// A unique identifier generated by the client to identify this request. - public var originId: String? - - /// Timestamp of when the event started in milliseconds since Epoch. - @CustomCodable - public var eventTime: Date? - - /// Message describing the task. - public var message: String? - - /// If known, total amount of work units in this task. - public var total: Int? - - /// If known, completed amount of work units in this task. - public var progress: Int? - - /// Name of a work unit. For example, "files" or "tests". May be empty. - public var unit: String? - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: TaskProgressDataKind? - - /// Optional metadata about the task. - /// - /// Objects for specific tasks like compile, test, etc are specified in the protocol. - public var data: LSPAny? - - public init( - taskId: TaskId, - originId: String? = nil, - eventTime: Date? = nil, - message: String? = nil, - total: Int? = nil, - progress: Int? = nil, - unit: String? = nil, - dataKind: TaskProgressDataKind? = nil, - data: LSPAny? = nil - ) { - self.taskId = taskId - self.originId = originId - self.eventTime = eventTime - self.message = message - self.total = total - self.progress = progress - self.unit = unit - self.dataKind = dataKind - self.data = data - } -} - -/// Task progress notifications may contain an arbitrary interface in their `data` field. -/// -/// The kind of interface that is contained in a notification must be specified in the `dataKind` field. -public struct TaskProgressDataKind: RawRepresentable, Codable, Hashable, Sendable { - public let rawValue: String - public init(rawValue: String) { - self.rawValue = rawValue - } -} diff --git a/Sources/BuildServerProtocol/Messages/TaskStartNotification.swift b/Sources/BuildServerProtocol/Messages/TaskStartNotification.swift deleted file mode 100644 index 444ee0c35..000000000 --- a/Sources/BuildServerProtocol/Messages/TaskStartNotification.swift +++ /dev/null @@ -1,158 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation -public import LanguageServerProtocol - -/// The BSP server can inform the client on the execution state of any task in the build tool. -/// The execution of some tasks, such as compilation or tests, must always be reported by the server. -/// -/// The server may also send additional task notifications for actions not covered by the protocol, such as resolution -/// or packaging. BSP clients can then display this information to their users at their discretion. -/// -/// When beginning a task, the server may send `build/taskStart`, intermediate updates may be sent in -/// `build/taskProgress`. -/// -/// If a `build/taskStart` notification has been sent, the server must send build/taskFinish on completion of the same -/// task. -/// -/// `build/taskStart`, `build/taskProgress` and `build/taskFinish` notifications for the same task must use the same -/// `taskId`. -/// -/// Tasks that are spawned by another task should reference the originating task's `taskId` in their own `taskId`'s -/// `parent` field. Tasks spawned directly by a request should reference the request's `originId` parent. -public struct TaskStartNotification: NotificationType { - public static let method: String = "build/taskStart" - - /// Unique id of the task with optional reference to parent task id - public var taskId: TaskId - - /// A unique identifier generated by the client to identify this request. - public var originId: String? - - /// Timestamp of when the event started in milliseconds since Epoch. - @CustomCodable - public var eventTime: Date? - - /// Message describing the task. - public var message: String? - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: TaskStartDataKind? - - /// Optional metadata about the task. - // Objects for specific tasks like compile, test, etc are specified in the protocol. - public var data: LSPAny? - - public init( - taskId: TaskId, - originId: String? = nil, - eventTime: Date? = nil, - message: String? = nil, - dataKind: TaskStartDataKind? = nil, - data: LSPAny? = nil - ) { - self.taskId = taskId - self.originId = originId - self.eventTime = eventTime - self.message = message - self.dataKind = dataKind - self.data = data - } -} - -/// Task start notifications may contain an arbitrary interface in their `data` field. -/// -/// The kind of interface that is contained in a notification must be specified in the `dataKind` field. -public struct TaskStartDataKind: RawRepresentable, Codable, Hashable, Sendable { - public let rawValue: String - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// `data` field must contain a `CompileTaskData` object. - public static let compileTask = TaskStartDataKind(rawValue: "compile-task") - - /// `data` field must contain a `TestStart` object. - public static let testStart = TaskStartDataKind(rawValue: "test-start") - - /// `data` field must contain a `TestTask` object. - public static let testTask = TaskStartDataKind(rawValue: "test-task") -} - -/// This structure is embedded in the `TaskStartNotification.data` field, when the `dataKind` field contains -/// "compile-task". -/// -/// The beginning of a compilation unit may be signalled to the client with a `build/taskStart` notification. -/// -/// When the compilation unit is a build target, the notification's `dataKind` field must be "compile-task" and the -/// `data` field must include a `CompileTaskData` object -public struct CompileTaskData: Codable, Hashable, Sendable { - public var target: BuildTargetIdentifier - - public init(target: BuildTargetIdentifier) { - self.target = target - } -} - -/// This structure is embedded in the `TaskStartNotification.data` field, when the `dataKind` field contains -/// "test-start". -public struct TestStartData: Codable, Hashable, Sendable { - /// Name or description of the test. - public var displayName: String - - /// Source location of the test, as LSP location. - public var location: Location? - - public init(displayName: String, location: Location? = nil) { - self.displayName = displayName - self.location = location - } -} - -/// This structure is embedded in the `TaskStartNotification.data` field, when the `dataKind` field contains -/// "test-task". -/// -/// The beginning of a testing unit may be signalled to the client with a `build/taskStart`` notification. -/// When the testing unit is a build target, the notification's `dataKind` field must be `test-task` and the `data` -/// field must include a `TestTaskData` object. -public struct TestTaskData: Codable, Hashable, Sendable { - public var target: BuildTargetIdentifier - - public init(target: BuildTargetIdentifier) { - self.target = target - } -} - -/// If `data` contains a string value for the `workDoneProgressTitle` key, then the task's message will be displayed in -/// the client as a work done progress with that title. -public struct WorkDoneProgressTask: LSPAnyCodable { - /// The title with which the work done progress should be created in the client. - public let title: String - - public init(title: String) { - self.title = title - } - - public init?(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) { - guard case .string(let title) = dictionary["workDoneProgressTitle"] else { - return nil - } - self.title = title - } - - public func encodeToLSPAny() -> LanguageServerProtocol.LSPAny { - return .dictionary([ - "workDoneProgressTitle": .string(title) - ]) - } -} diff --git a/Sources/BuildServerProtocol/Messages/TextDocumentSourceKitOptionsRequest.swift b/Sources/BuildServerProtocol/Messages/TextDocumentSourceKitOptionsRequest.swift deleted file mode 100644 index fc008c15c..000000000 --- a/Sources/BuildServerProtocol/Messages/TextDocumentSourceKitOptionsRequest.swift +++ /dev/null @@ -1,61 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The `TextDocumentSourceKitOptionsRequest` request is sent from the client to the server to query for the list of -/// compiler options necessary to compile this file in the given target. -/// -/// The build settings are considered up-to-date and can be cached by SourceKit-LSP until a -/// `DidChangeBuildTargetNotification` is sent for the requested target. -/// -/// The request may return `nil` if it doesn't have any build settings for this file in the given target. -public struct TextDocumentSourceKitOptionsRequest: RequestType, Hashable { - public static let method: String = "textDocument/sourceKitOptions" - public typealias Response = TextDocumentSourceKitOptionsResponse? - - /// The URI of the document to get options for - public var textDocument: TextDocumentIdentifier - - /// The target for which the build setting should be returned. - /// - /// A source file might be part of multiple targets and might have different compiler arguments in those two targets, - /// thus the target is necessary in this request. - public var target: BuildTargetIdentifier - - /// The language with which the document was opened in the editor. - public var language: Language - - public init(textDocument: TextDocumentIdentifier, target: BuildTargetIdentifier, language: Language) { - self.textDocument = textDocument - self.target = target - self.language = language - } -} - -public struct TextDocumentSourceKitOptionsResponse: ResponseType, Hashable { - /// The compiler options required for the requested file. - public var compilerArguments: [String] - - /// The working directory for the compile command. - public var workingDirectory: String? - - /// Additional data that will not be interpreted by SourceKit-LSP but made available to clients in the - /// `workspace/_sourceKitOptions` LSP requests. - public var data: LSPAny? - - public init(compilerArguments: [String], workingDirectory: String? = nil, data: LSPAny? = nil) { - self.compilerArguments = compilerArguments - self.workingDirectory = workingDirectory - self.data = data - } -} diff --git a/Sources/BuildServerProtocol/Messages/WorkspaceBuildTargetsRequest.swift b/Sources/BuildServerProtocol/Messages/WorkspaceBuildTargetsRequest.swift deleted file mode 100644 index 24991c588..000000000 --- a/Sources/BuildServerProtocol/Messages/WorkspaceBuildTargetsRequest.swift +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// The workspace build targets request is sent from the client to the server to -/// ask for the list of all available build targets in the workspace. -public struct WorkspaceBuildTargetsRequest: RequestType, Hashable { - public static let method: String = "workspace/buildTargets" - public typealias Response = WorkspaceBuildTargetsResponse - - public init() {} -} - -public struct WorkspaceBuildTargetsResponse: ResponseType, Hashable { - /// The build targets in this workspace that contain sources with the given language ids. - public var targets: [BuildTarget] - - public init(targets: [BuildTarget]) { - self.targets = targets - } -} diff --git a/Sources/BuildServerProtocol/Messages/WorkspaceWaitForBuildSystemUpdates.swift b/Sources/BuildServerProtocol/Messages/WorkspaceWaitForBuildSystemUpdates.swift deleted file mode 100644 index 3fa579ade..000000000 --- a/Sources/BuildServerProtocol/Messages/WorkspaceWaitForBuildSystemUpdates.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// This request is a no-op and doesn't have any effects. -/// -/// If the build server is currently updating the build graph, this request should return after those updates have -/// finished processing. -public struct WorkspaceWaitForBuildSystemUpdatesRequest: RequestType, Hashable { - public typealias Response = VoidResponse - - public static let method: String = "workspace/waitForBuildSystemUpdates" - - public init() {} -} diff --git a/Sources/BuildServerProtocol/SupportTypes/BuildTarget.swift b/Sources/BuildServerProtocol/SupportTypes/BuildTarget.swift deleted file mode 100644 index 266f20ab5..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/BuildTarget.swift +++ /dev/null @@ -1,237 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -/// Build target contains metadata about an artifact (for example library, test, or binary artifact). -/// Using vocabulary of other build tools: -/// - sbt: a build target is a combined project + config. Example: -/// - a regular JVM project with main and test configurations will have 2 build targets, one for main and one for test. -/// - a single configuration in a single project that contains both Java and Scala sources maps to one BuildTarget. -/// - a project with crossScalaVersions 2.11 and 2.12 containing main and test configuration in each will have 4 build targets. -/// - a Scala 2.11 and 2.12 cross-built project for Scala.js and the JVM with main and test configurations will have 8 build targets. -/// - Pants: a pants target corresponds one-to-one with a BuildTarget -/// - Bazel: a bazel target corresponds one-to-one with a BuildTarget -/// -/// The general idea is that the BuildTarget data structure should contain only information that is fast or cheap to compute -public struct BuildTarget: Codable, Hashable, Sendable { - /// The target’s unique identifier - public var id: BuildTargetIdentifier - - /// A human readable name for this target. - /// May be presented in the user interface. - /// Should be unique if possible. - /// The id.uri is used if `nil`. - public var displayName: String? - - /// The directory where this target belongs to. Multiple build targets are - /// allowed to map to the same base directory, and a build target is not - /// required to have a base directory. A base directory does not determine the - /// sources of a target, see `buildTarget/sources`. - public var baseDirectory: URI? - - /// Free-form string tags to categorize or label this build target. - /// For example, can be used by the client to: - /// - customize how the target should be translated into the client's project - /// model. - /// - group together different but related targets in the user interface. - /// - display icons or colors in the user interface. - /// Pre-defined tags are listed in `BuildTargetTag` but clients and servers - /// are free to define new tags for custom purposes. - public var tags: [BuildTargetTag] - - /// The set of languages that this target contains. - /// The ID string for each language is defined in the LSP. - public var languageIds: [Language] - - /// The direct upstream build target dependencies of this build target - public var dependencies: [BuildTargetIdentifier] - - /// The capabilities of this build target. - public var capabilities: BuildTargetCapabilities - - /// Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. - public var dataKind: BuildTargetDataKind? - - /// Language-specific metadata about this target. - /// See ScalaBuildTarget as an example. - public var data: LSPAny? - - public init( - id: BuildTargetIdentifier, - displayName: String? = nil, - baseDirectory: URI? = nil, - tags: [BuildTargetTag] = [], - capabilities: BuildTargetCapabilities = BuildTargetCapabilities(), - languageIds: [Language], - dependencies: [BuildTargetIdentifier], - dataKind: BuildTargetDataKind? = nil, - data: LSPAny? = nil - ) { - self.id = id - self.displayName = displayName - self.baseDirectory = baseDirectory - self.tags = tags - self.capabilities = capabilities - self.languageIds = languageIds - self.dependencies = dependencies - self.dataKind = dataKind - self.data = data - } -} - -/// A unique identifier for a target, can use any URI-compatible encoding as long as it is unique within the workspace. -/// Clients should not infer metadata out of the URI structure such as the path or query parameters, use `BuildTarget` -/// instead. -public struct BuildTargetIdentifier: Codable, Hashable, Sendable { - /// The target's Uri - public var uri: URI - - public init(uri: URI) { - self.uri = uri - } -} - -public typealias URI = DocumentURI - -/// A list of predefined tags that can be used to categorize build targets. -public struct BuildTargetTag: Codable, Hashable, RawRepresentable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// Target contains source code for producing any kind of application, may - /// have but does not require the `canRun` capability. - public static let application: Self = Self(rawValue: "application") - - /// Target contains source code to measure performance of a program, may have - /// but does not require the `canRun` build target capability. - public static let benchmark: Self = Self(rawValue: "benchmark") - - /// Target contains source code for integration testing purposes, may have - /// but does not require the `canTest` capability. The difference between - /// "test" and "integration-test" is that integration tests traditionally run - /// slower compared to normal tests and require more computing resources to - /// execute. - public static let integrationTest: Self = Self(rawValue: "integration-test") - - /// Target contains re-usable functionality for downstream targets. May have - /// any combination of capabilities. - public static let library: Self = Self(rawValue: "library") - - /// Actions on the target such as build and test should only be invoked manually - /// and explicitly. For example, triggering a build on all targets in the workspace - /// should by default not include this target. - /// The original motivation to add the "manual" tag comes from a similar functionality - /// that exists in Bazel, where targets with this tag have to be specified explicitly - /// on the command line. - public static let manual: Self = Self(rawValue: "manual") - - /// Target should be ignored by IDEs. - public static let noIDE: Self = Self(rawValue: "no-ide") - - /// Target contains source code for testing purposes, may have but does not - /// require the `canTest` capability. - public static let test: Self = Self(rawValue: "test") - - /// This is a target of a dependency from the project the user opened, eg. a target that builds a SwiftPM dependency. - /// - /// **(BSP Extension)** - public static let dependency: Self = Self(rawValue: "dependency") - - /// This target only exists to provide compiler arguments for SourceKit-LSP can't be built standalone. - /// - /// For example, a SwiftPM package manifest is in a non-buildable target. - /// - /// **(BSP Extension)** - public static let notBuildable: Self = Self(rawValue: "not-buildable") -} - -/// Clients can use these capabilities to notify users what BSP endpoints can and cannot be used and why. -public struct BuildTargetCapabilities: Codable, Hashable, Sendable { - /// This target can be compiled by the BSP server. - public var canCompile: Bool? - - /// This target can be tested by the BSP server. - public var canTest: Bool? - - /// This target can be run by the BSP server. - public var canRun: Bool? - - /// This target can be debugged by the BSP server. - public var canDebug: Bool? - - public init(canCompile: Bool? = nil, canTest: Bool? = nil, canRun: Bool? = nil, canDebug: Bool? = nil) { - self.canCompile = canCompile - self.canTest = canTest - self.canRun = canRun - self.canDebug = canDebug - } -} - -public struct BuildTargetDataKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// `data` field must contain a CargoBuildTarget object. - public static let cargo = BuildTargetDataKind(rawValue: "cargo") - - /// `data` field must contain a CppBuildTarget object. - public static let cpp = BuildTargetDataKind(rawValue: "cpp") - - /// `data` field must contain a JvmBuildTarget object. - public static let jvm = BuildTargetDataKind(rawValue: "jvm") - - /// `data` field must contain a PythonBuildTarget object. - public static let python = BuildTargetDataKind(rawValue: "python") - - /// `data` field must contain a SbtBuildTarget object. - public static let sbt = BuildTargetDataKind(rawValue: "sbt") - - /// `data` field must contain a ScalaBuildTarget object. - public static let scala = BuildTargetDataKind(rawValue: "scala") - - /// `data` field must contain a SourceKitBuildTarget object. - public static let sourceKit = BuildTargetDataKind(rawValue: "sourceKit") -} - -public struct SourceKitBuildTarget: LSPAnyCodable, Codable { - /// The toolchain that should be used to build this target. The URI should point to the directory that contains the - /// `usr` directory. On macOS, this is typically a bundle ending in `.xctoolchain`. If the toolchain is installed to - /// `/` on Linux, the toolchain URI would point to `/`. - /// - /// If no toolchain is given, SourceKit-LSP will pick a toolchain to use for this target. - public var toolchain: URI? - - public init(toolchain: URI? = nil) { - self.toolchain = toolchain - } - - public init(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) { - if case .string(let toolchain) = dictionary[CodingKeys.toolchain.stringValue] { - self.toolchain = try? URI(string: toolchain) - } - } - - public func encodeToLSPAny() -> LanguageServerProtocol.LSPAny { - var result: [String: LSPAny] = [:] - if let toolchain { - result[CodingKeys.toolchain.stringValue] = .string(toolchain.stringValue) - } - return .dictionary(result) - } -} diff --git a/Sources/BuildServerProtocol/SupportTypes/MessageType.swift b/Sources/BuildServerProtocol/SupportTypes/MessageType.swift deleted file mode 100644 index 3e18cf2fa..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/MessageType.swift +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol - -public enum MessageType: Int, Sendable, Codable { - /// An error message. - case error = 1 - - /// A warning message. - case warning = 2 - - /// An information message. - case info = 3 - - /// A log message. - case log = 4 -} diff --git a/Sources/BuildServerProtocol/SupportTypes/MillisecondsSince1970Date.swift b/Sources/BuildServerProtocol/SupportTypes/MillisecondsSince1970Date.swift deleted file mode 100644 index 256e46861..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/MillisecondsSince1970Date.swift +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation -public import LanguageServerProtocol - -public struct MillisecondsSince1970Date: CustomCodableWrapper { - public var wrappedValue: Date - - public init(wrappedValue: Date) { - self.wrappedValue = wrappedValue - } - - public init(from decoder: any Decoder) throws { - let millisecondsSince1970 = try decoder.singleValueContainer().decode(Int64.self) - self.wrappedValue = Date(timeIntervalSince1970: Double(millisecondsSince1970) / 1_000) - } - - public func encode(to encoder: any Encoder) throws { - let millisecondsSince1970 = Int64((wrappedValue.timeIntervalSince1970 * 1_000).rounded()) - var container = encoder.singleValueContainer() - try container.encode(millisecondsSince1970) - } -} diff --git a/Sources/BuildServerProtocol/SupportTypes/StatusCode.swift b/Sources/BuildServerProtocol/SupportTypes/StatusCode.swift deleted file mode 100644 index 109a0be47..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/StatusCode.swift +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum StatusCode: Int, Codable, Hashable, Sendable { - /// Execution was successful. - case ok = 1 - - /// Execution failed. - case error = 2 - - /// Execution was cancelled. - case cancelled = 3 -} diff --git a/Sources/BuildServerProtocol/SupportTypes/TaskId.swift b/Sources/BuildServerProtocol/SupportTypes/TaskId.swift deleted file mode 100644 index ab5dc867d..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/TaskId.swift +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol - -public typealias TaskIdentifier = String - -public struct TaskId: Sendable, Codable, Hashable { - /// A unique identifier - public var id: TaskIdentifier - - /// The parent task ids, if any. A non-empty parents field means - /// this task is a sub-task of every parent task id. The child-parent - /// relationship of tasks makes it possible to render tasks in - /// a tree-like user interface or inspect what caused a certain task - /// execution. - /// OriginId should not be included in the parents field, there is a separate - /// field for that. - public var parents: [TaskIdentifier]? - - public init(id: TaskIdentifier, parents: [TaskIdentifier]? = nil) { - self.id = id - self.parents = parents - } -} diff --git a/Sources/BuildServerProtocol/SupportTypes/TextDocumentIdentifier.swift b/Sources/BuildServerProtocol/SupportTypes/TextDocumentIdentifier.swift deleted file mode 100644 index 259294307..000000000 --- a/Sources/BuildServerProtocol/SupportTypes/TextDocumentIdentifier.swift +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import LanguageServerProtocol - -public struct TextDocumentIdentifier: Codable, Sendable, Hashable { - /// The text document's URI. - public var uri: URI - - public init(_ uri: URI) { - self.uri = uri - } -} diff --git a/Sources/CAtomics/CAtomics.c b/Sources/CAtomics/CAtomics.c deleted file mode 100644 index f6d1c10c4..000000000 --- a/Sources/CAtomics/CAtomics.c +++ /dev/null @@ -1,11 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// diff --git a/Sources/CAtomics/CMakeLists.txt b/Sources/CAtomics/CMakeLists.txt deleted file mode 100644 index 9ed253763..000000000 --- a/Sources/CAtomics/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_library(CAtomics INTERFACE) -target_include_directories(CAtomics INTERFACE "include") diff --git a/Sources/CAtomics/include/CAtomics.h b/Sources/CAtomics/include/CAtomics.h deleted file mode 100644 index fc659a311..000000000 --- a/Sources/CAtomics/include/CAtomics.h +++ /dev/null @@ -1,73 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#ifndef SOURCEKITLSP_CATOMICS_H -#define SOURCEKITLSP_CATOMICS_H - -#include -#include -#include -#include - -typedef struct { - _Atomic(uint32_t) value; -} CAtomicUInt32; - -static inline CAtomicUInt32 *_Nonnull atomic_uint32_create(uint32_t initialValue) { - CAtomicUInt32 *atomic = malloc(sizeof(CAtomicUInt32)); - atomic->value = initialValue; - return atomic; -} - -static inline uint32_t atomic_uint32_get(CAtomicUInt32 *_Nonnull atomic) { - return atomic->value; -} - -static inline void atomic_uint32_set(CAtomicUInt32 *_Nonnull atomic, uint32_t newValue) { - atomic->value = newValue; -} - -static inline uint32_t atomic_uint32_fetch_and_increment(CAtomicUInt32 *_Nonnull atomic) { - return atomic->value++; -} - -static inline void atomic_uint32_destroy(CAtomicUInt32 *_Nonnull atomic) { - free(atomic); -} - -typedef struct { - _Atomic(int32_t) value; -} CAtomicInt32; - -static inline CAtomicInt32 *_Nonnull atomic_int32_create(int32_t initialValue) { - CAtomicInt32 *atomic = malloc(sizeof(CAtomicInt32)); - atomic->value = initialValue; - return atomic; -} - -static inline int32_t atomic_int32_get(CAtomicInt32 *_Nonnull atomic) { - return atomic->value; -} - -static inline void atomic_int32_set(CAtomicInt32 *_Nonnull atomic, int32_t newValue) { - atomic->value = newValue; -} - -static inline int32_t atomic_int32_fetch_and_increment(CAtomicInt32 *_Nonnull atomic) { - return atomic->value++; -} - -static inline void atomic_int32_destroy(CAtomicInt32 *_Nonnull atomic) { - free(atomic); -} - -#endif // SOURCEKITLSP_CATOMICS_H diff --git a/Sources/CAtomics/include/module.modulemap b/Sources/CAtomics/include/module.modulemap deleted file mode 100644 index 0e9d1d3ed..000000000 --- a/Sources/CAtomics/include/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module CAtomics { - header "CAtomics.h" - export * -} diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 8460311a1..eb373e69c 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -2,19 +2,14 @@ add_compile_options("$<$:SHELL:-package-name sourcekit_l add_compile_options("$<$:SHELL:-DRESILIENT_LIBRARIES>") add_compile_options("$<$:SHELL:-swift-version 6>") add_subdirectory(BuildServerIntegration) -add_subdirectory(BuildServerProtocol) -add_subdirectory(CAtomics) add_subdirectory(CCompletionScoring) add_subdirectory(ClangLanguageService) add_subdirectory(CompletionScoring) add_subdirectory(Csourcekitd) add_subdirectory(Diagnose) add_subdirectory(InProcessClient) -add_subdirectory(LanguageServerProtocol) add_subdirectory(LanguageServerProtocolExtensions) -add_subdirectory(LanguageServerProtocolJSONRPC) add_subdirectory(SemanticIndex) -add_subdirectory(SKLogging) add_subdirectory(SKOptions) add_subdirectory(SKUtilities) add_subdirectory(sourcekit-lsp) diff --git a/Sources/ClangLanguageService/CMakeLists.txt b/Sources/ClangLanguageService/CMakeLists.txt index 8ea42c567..f9ab7cd20 100644 --- a/Sources/ClangLanguageService/CMakeLists.txt +++ b/Sources/ClangLanguageService/CMakeLists.txt @@ -8,10 +8,11 @@ set_target_properties(ClangLanguageService PROPERTIES ) target_link_libraries(ClangLanguageService PUBLIC - LanguageServerProtocol + SwiftToolsProtocols::LanguageServerProtocol SKOptions SourceKitLSP SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions ToolchainRegistry SwiftSyntax::SwiftSyntax ) @@ -19,7 +20,7 @@ target_link_libraries(ClangLanguageService PUBLIC target_link_libraries(ClangLanguageService PRIVATE BuildServerIntegration LanguageServerProtocolExtensions - LanguageServerProtocolJSONRPC - SKLogging + SwiftToolsProtocols::LanguageServerProtocolTransport + SwiftToolsProtocols::SKLogging TSCExtensions ) diff --git a/Sources/ClangLanguageService/ClangLanguageService.swift b/Sources/ClangLanguageService/ClangLanguageService.swift index e8946851d..1997fc9df 100644 --- a/Sources/ClangLanguageService/ClangLanguageService.swift +++ b/Sources/ClangLanguageService/ClangLanguageService.swift @@ -13,16 +13,17 @@ import BuildServerIntegration import Foundation import IndexStoreDB -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging package import SKOptions package import SourceKitLSP -package import SwiftExtensions +import SwiftExtensions package import SwiftSyntax import TSCExtensions package import ToolchainRegistry +@_spi(SourceKitLSP) package import ToolsProtocolsSwiftExtensions #if os(Windows) import WinSDK diff --git a/Sources/ClangLanguageService/SemanticTokenTranslator.swift b/Sources/ClangLanguageService/SemanticTokenTranslator.swift index 80aa5efa9..425a697be 100644 --- a/Sources/ClangLanguageService/SemanticTokenTranslator.swift +++ b/Sources/ClangLanguageService/SemanticTokenTranslator.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging /// `clangd` might use a different semantic token legend than SourceKit-LSP. /// diff --git a/Sources/CompletionScoringTestSupport/TestExtensions.swift b/Sources/CompletionScoringTestSupport/TestExtensions.swift index 54dd9cb90..13eb99dbb 100644 --- a/Sources/CompletionScoringTestSupport/TestExtensions.swift +++ b/Sources/CompletionScoringTestSupport/TestExtensions.swift @@ -13,6 +13,7 @@ package import CompletionScoring import Foundation import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest @inline(never) diff --git a/Sources/Diagnose/CMakeLists.txt b/Sources/Diagnose/CMakeLists.txt index 4ed6d14e9..24fba80a7 100644 --- a/Sources/Diagnose/CMakeLists.txt +++ b/Sources/Diagnose/CMakeLists.txt @@ -28,10 +28,11 @@ set_target_properties(Diagnose PROPERTIES target_link_libraries(Diagnose PUBLIC BuildServerIntegration InProcessClient - SKLogging + SwiftToolsProtocols::SKLogging SKOptions SourceKitD SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions ToolchainRegistry ArgumentParser SwiftSyntax::SwiftIDEUtils diff --git a/Sources/Diagnose/CommandLineArgumentsReducer.swift b/Sources/Diagnose/CommandLineArgumentsReducer.swift index ecea363b9..de92cf9f6 100644 --- a/Sources/Diagnose/CommandLineArgumentsReducer.swift +++ b/Sources/Diagnose/CommandLineArgumentsReducer.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging // MARK: - Entry point diff --git a/Sources/Diagnose/DiagnoseCommand.swift b/Sources/Diagnose/DiagnoseCommand.swift index 5a251f23d..d43e01f7a 100644 --- a/Sources/Diagnose/DiagnoseCommand.swift +++ b/Sources/Diagnose/DiagnoseCommand.swift @@ -12,11 +12,12 @@ package import ArgumentParser import Foundation -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions import TSCExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import class TSCBasic.Process diff --git a/Sources/Diagnose/IndexCommand.swift b/Sources/Diagnose/IndexCommand.swift index 5b782014d..a073949df 100644 --- a/Sources/Diagnose/IndexCommand.swift +++ b/Sources/Diagnose/IndexCommand.swift @@ -13,12 +13,14 @@ public import ArgumentParser import Foundation import InProcessClient -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport import SKOptions import SourceKitLSP import SwiftExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import class TSCBasic.Process diff --git a/Sources/Diagnose/MergeSwiftFiles.swift b/Sources/Diagnose/MergeSwiftFiles.swift index 1cfa401cb..13cc0834e 100644 --- a/Sources/Diagnose/MergeSwiftFiles.swift +++ b/Sources/Diagnose/MergeSwiftFiles.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging extension RequestInfo { /// Check if the issue reproduces when merging all `.swift` input files into a single file. diff --git a/Sources/Diagnose/OSLogScraper.swift b/Sources/Diagnose/OSLogScraper.swift index 287c79e5b..a2ffb2c73 100644 --- a/Sources/Diagnose/OSLogScraper.swift +++ b/Sources/Diagnose/OSLogScraper.swift @@ -12,7 +12,7 @@ #if canImport(OSLog) import OSLog -import SKLogging +@_spi(SourceKitLSP) import SKLogging import RegexBuilder /// Reads oslog messages to find recent sourcekitd crashes. diff --git a/Sources/Diagnose/RunSourcekitdRequestCommand.swift b/Sources/Diagnose/RunSourcekitdRequestCommand.swift index 63e81899d..a1f417909 100644 --- a/Sources/Diagnose/RunSourcekitdRequestCommand.swift +++ b/Sources/Diagnose/RunSourcekitdRequestCommand.swift @@ -13,7 +13,7 @@ package import ArgumentParser import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitD import SwiftExtensions diff --git a/Sources/Diagnose/SourceReducer.swift b/Sources/Diagnose/SourceReducer.swift index 6cdb250df..5d8d78727 100644 --- a/Sources/Diagnose/SourceReducer.swift +++ b/Sources/Diagnose/SourceReducer.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SwiftExtensions @_spi(FixItApplier) import SwiftIDEUtils diff --git a/Sources/DocumentationLanguageService/BuildSystemIntegrationExtensions.swift b/Sources/DocumentationLanguageService/BuildSystemIntegrationExtensions.swift index 8af477ed4..80b807909 100644 --- a/Sources/DocumentationLanguageService/BuildSystemIntegrationExtensions.swift +++ b/Sources/DocumentationLanguageService/BuildSystemIntegrationExtensions.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging extension BuildServerManager { /// Retrieves the name of the Swift module for a given target. diff --git a/Sources/DocumentationLanguageService/DocCCatalogIndexManager.swift b/Sources/DocumentationLanguageService/DocCCatalogIndexManager.swift index ad15a090d..440dd1568 100644 --- a/Sources/DocumentationLanguageService/DocCCatalogIndexManager.swift +++ b/Sources/DocumentationLanguageService/DocCCatalogIndexManager.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKUtilities @_spi(LinkCompletion) @preconcurrency import SwiftDocC diff --git a/Sources/DocumentationLanguageService/DocCDocumentationManager.swift b/Sources/DocumentationLanguageService/DocCDocumentationManager.swift index 970a3a426..39fd0a549 100644 --- a/Sources/DocumentationLanguageService/DocCDocumentationManager.swift +++ b/Sources/DocumentationLanguageService/DocCDocumentationManager.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SwiftDocC struct DocCDocumentationManager: Sendable { diff --git a/Sources/DocumentationLanguageService/DocCReferenceResolutionService.swift b/Sources/DocumentationLanguageService/DocCReferenceResolutionService.swift index 220056084..549d9040b 100644 --- a/Sources/DocumentationLanguageService/DocCReferenceResolutionService.swift +++ b/Sources/DocumentationLanguageService/DocCReferenceResolutionService.swift @@ -12,8 +12,8 @@ import Foundation import IndexStoreDB -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SemanticIndex @_spi(Linkcompletion) @preconcurrency import SwiftDocC import SwiftExtensions diff --git a/Sources/DocumentationLanguageService/DoccDocumentationError.swift b/Sources/DocumentationLanguageService/DoccDocumentationError.swift index 07247a348..695efa1d5 100644 --- a/Sources/DocumentationLanguageService/DoccDocumentationError.swift +++ b/Sources/DocumentationLanguageService/DoccDocumentationError.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol enum DocCDocumentationError: LocalizedError { case unsupportedLanguage(Language) diff --git a/Sources/DocumentationLanguageService/DoccDocumentationHandler.swift b/Sources/DocumentationLanguageService/DoccDocumentationHandler.swift index 6db2ee025..bfe815866 100644 --- a/Sources/DocumentationLanguageService/DoccDocumentationHandler.swift +++ b/Sources/DocumentationLanguageService/DoccDocumentationHandler.swift @@ -13,9 +13,9 @@ import BuildServerIntegration import Foundation @preconcurrency import IndexStoreDB -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import Markdown -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SemanticIndex import SourceKitLSP diff --git a/Sources/DocumentationLanguageService/DocumentationLanguageService.swift b/Sources/DocumentationLanguageService/DocumentationLanguageService.swift index a3a8eff25..af87658d3 100644 --- a/Sources/DocumentationLanguageService/DocumentationLanguageService.swift +++ b/Sources/DocumentationLanguageService/DocumentationLanguageService.swift @@ -12,7 +12,7 @@ import Foundation import IndexStoreDB -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol package import SKOptions package import SourceKitLSP import SwiftExtensions diff --git a/Sources/DocumentationLanguageService/IndexStoreDB+Extensions.swift b/Sources/DocumentationLanguageService/IndexStoreDB+Extensions.swift index fe5922ddd..924be993d 100644 --- a/Sources/DocumentationLanguageService/IndexStoreDB+Extensions.swift +++ b/Sources/DocumentationLanguageService/IndexStoreDB+Extensions.swift @@ -12,7 +12,7 @@ import Foundation import IndexStoreDB -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SemanticIndex @preconcurrency @_spi(LinkCompletion) import SwiftDocC import SwiftExtensions diff --git a/Sources/InProcessClient/CMakeLists.txt b/Sources/InProcessClient/CMakeLists.txt index 1c8646ff1..459ad52a3 100644 --- a/Sources/InProcessClient/CMakeLists.txt +++ b/Sources/InProcessClient/CMakeLists.txt @@ -8,8 +8,8 @@ set_target_properties(InProcessClient PROPERTIES target_link_libraries(InProcessClient PUBLIC BuildServerIntegration ClangLanguageService - LanguageServerProtocol - SKLogging + SwiftToolsProtocols::LanguageServerProtocol + SwiftToolsProtocols::SKLogging SKOptions SourceKitLSP SwiftLanguageService diff --git a/Sources/InProcessClient/InProcessSourceKitLSPClient.swift b/Sources/InProcessClient/InProcessSourceKitLSPClient.swift index 928461ef1..8b68c6bdd 100644 --- a/Sources/InProcessClient/InProcessSourceKitLSPClient.swift +++ b/Sources/InProcessClient/InProcessSourceKitLSPClient.swift @@ -12,14 +12,16 @@ import BuildServerIntegration public import Foundation -public import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) public import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging public import SKOptions package import SourceKitLSP import SwiftExtensions import TSCExtensions package import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath diff --git a/Sources/InProcessClient/LanguageServiceRegistry+staticallyKnownServices.swift b/Sources/InProcessClient/LanguageServiceRegistry+staticallyKnownServices.swift index ca95726d0..0d39bf717 100644 --- a/Sources/InProcessClient/LanguageServiceRegistry+staticallyKnownServices.swift +++ b/Sources/InProcessClient/LanguageServiceRegistry+staticallyKnownServices.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import ClangLanguageService -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol package import SourceKitLSP import SwiftLanguageService diff --git a/Sources/LanguageServerProtocol/CMakeLists.txt b/Sources/LanguageServerProtocol/CMakeLists.txt deleted file mode 100644 index 9c05561bd..000000000 --- a/Sources/LanguageServerProtocol/CMakeLists.txt +++ /dev/null @@ -1,155 +0,0 @@ -add_library(LanguageServerProtocol STATIC - Connection.swift - CustomCodable.swift - Error.swift - Message.swift - MessageRegistry.swift - Messages.swift - PositionRange.swift - RequestID.swift - - Notifications/CancelRequestNotification.swift - Notifications/CancelWorkDoneProgressNotification.swift - Notifications/ConfigurationNotification.swift - Notifications/DidChangeActiveDocumentNotification.swift - Notifications/DidChangeFileNotifications.swift - Notifications/DidChangeWatchedFilesNotification.swift - Notifications/DidChangeWorkspaceFoldersNotification.swift - Notifications/ExitNotification.swift - Notifications/InitializedNotification.swift - Notifications/LogMessageNotification.swift - Notifications/LogTraceNotification.swift - Notifications/PublishDiagnosticsNotification.swift - Notifications/ReopenTextDocumentNotifications.swift - Notifications/SetTraceNotification.swift - Notifications/ShowMessageNotification.swift - Notifications/TextSynchronizationNotifications.swift - Notifications/WorkDoneProgress.swift - - Requests/ApplyEditRequest.swift - Requests/CallHierarchyIncomingCallsRequest.swift - Requests/CallHierarchyOutgoingCallsRequest.swift - Requests/CallHierarchyPrepareRequest.swift - Requests/CodeActionRequest.swift - Requests/CodeActionResolveRequest.swift - Requests/CodeLensRefreshRequest.swift - Requests/CodeLensRequest.swift - Requests/CodeLensResolveRequest.swift - Requests/ColorPresentationRequest.swift - Requests/CompletionItemResolveRequest.swift - Requests/CompletionRequest.swift - Requests/CreateWorkDoneProgressRequest.swift - Requests/DeclarationRequest.swift - Requests/DefinitionRequest.swift - Requests/DiagnosticsRefreshRequest.swift - Requests/DoccDocumentationRequest.swift - Requests/DocumentColorRequest.swift - Requests/DocumentDiagnosticsRequest.swift - Requests/DocumentHighlightRequest.swift - Requests/DocumentLinkRequest.swift - Requests/DocumentLinkResolveRequest.swift - Requests/DocumentSemanticTokensDeltaRequest.swift - Requests/DocumentSemanticTokensRangeRequest.swift - Requests/DocumentSemanticTokensRequest.swift - Requests/DocumentSymbolRequest.swift - Requests/DocumentTestsRequest.swift - Requests/ExecuteCommandRequest.swift - Requests/FoldingRangeRequest.swift - Requests/FormattingRequests.swift - Requests/GetReferenceDocumentRequest.swift - Requests/HoverRequest.swift - Requests/ImplementationRequest.swift - Requests/IndexedRenameRequest.swift - Requests/InitializeRequest.swift - Requests/InlayHintRefreshRequest.swift - Requests/InlayHintRequest.swift - Requests/InlayHintResolveRequest.swift - Requests/InlineValueRefreshRequest.swift - Requests/InlineValueRequest.swift - Requests/IsIndexingRequest.swift - Requests/LinkedEditingRangeRequest.swift - Requests/MonikersRequest.swift - Requests/OutputPathsRequest.swift - Requests/PeekDocumentsRequest.swift - Requests/PrepareRenameRequest.swift - Requests/ReferencesRequest.swift - Requests/RegisterCapabilityRequest.swift - Requests/RenameRequest.swift - Requests/SelectionRangeRequest.swift - Requests/SetOptionsRequest.swift - Requests/ShowDocumentRequest.swift - Requests/ShowMessageRequest.swift - Requests/ShutdownRequest.swift - Requests/SignatureHelpRequest.swift - Requests/SourceKitOptionsRequest.swift - Requests/SymbolInfoRequest.swift - Requests/SynchronizeRequest.swift - Requests/TriggerReindexRequest.swift - Requests/TypeDefinitionRequest.swift - Requests/TypeHierarchyPrepareRequest.swift - Requests/TypeHierarchySubtypesRequest.swift - Requests/TypeHierarchySupertypesRequest.swift - Requests/UnregisterCapabilityRequest.swift - Requests/WillChangeFilesRequests.swift - Requests/WillSaveWaitUntilTextDocumentRequest.swift - Requests/WorkspaceDiagnosticsRequest.swift - Requests/WorkspaceFoldersRequest.swift - Requests/WorkspaceSemanticTokensRefreshRequest.swift - Requests/WorkspaceSymbolResolveRequest.swift - Requests/WorkspaceSymbolsRequest.swift - Requests/WorkspaceTestsRequest.swift - - SupportTypes/CallHierarchyItem.swift - SupportTypes/ClientCapabilities.swift - SupportTypes/CodeActionKind.swift - SupportTypes/Command.swift - SupportTypes/CompletionItem.swift - SupportTypes/CompletionItemKind.swift - SupportTypes/Diagnostic.swift - SupportTypes/DocumentURI.swift - SupportTypes/FileEvent.swift - SupportTypes/FileSystemWatcher.swift - SupportTypes/FoldingRangeKind.swift - SupportTypes/InlayHint.swift - SupportTypes/InsertReplaceEdit.swift - SupportTypes/Language.swift - SupportTypes/Location.swift - SupportTypes/LocationLink.swift - SupportTypes/LocationsOrLocationLinksResponse.swift - SupportTypes/LSPAny.swift - SupportTypes/MarkupContent.swift - SupportTypes/NotebookCellTextDocumentFilter.swift - SupportTypes/NotebookDocument.swift - SupportTypes/NotebookDocumentChangeEvent.swift - SupportTypes/NotebookDocumentIdentifier.swift - SupportTypes/Position.swift - SupportTypes/PositionEncoding.swift - SupportTypes/ProgressToken.swift - SupportTypes/RegistrationOptions.swift - SupportTypes/SemanticTokenModifiers.swift - SupportTypes/SemanticTokens.swift - SupportTypes/SemanticTokenTypes.swift - SupportTypes/ServerCapabilities.swift - SupportTypes/StringOrMarkupContent.swift - SupportTypes/SupportedCodeLensCommand.swift - SupportTypes/SymbolKind.swift - SupportTypes/TestItem.swift - SupportTypes/TextDocumentContentChangeEvent.swift - SupportTypes/TextDocumentEdit.swift - SupportTypes/TextDocumentIdentifier.swift - SupportTypes/TextDocumentItem.swift - SupportTypes/TextDocumentSaveReason.swift - SupportTypes/TextEdit.swift - SupportTypes/Tracing.swift - SupportTypes/TypeHierarchyItem.swift - SupportTypes/VersionedNotebookDocumentIdentifier.swift - SupportTypes/VersionedTextDocumentIdentifier.swift - SupportTypes/WindowMessageType.swift - SupportTypes/WorkspaceEdit.swift - SupportTypes/WorkspaceFolder.swift - SupportTypes/WorkspaceSettings.swift) -set_target_properties(LanguageServerProtocol PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -target_link_libraries(LanguageServerProtocol PUBLIC - $<$>:swiftDispatch> - $<$>:Foundation>) diff --git a/Sources/LanguageServerProtocol/Connection.swift b/Sources/LanguageServerProtocol/Connection.swift deleted file mode 100644 index 8d743eaf9..000000000 --- a/Sources/LanguageServerProtocol/Connection.swift +++ /dev/null @@ -1,103 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// An abstract connection, allow messages to be sent to a (potentially remote) `MessageHandler`. -public protocol Connection: Sendable { - /// Send a notification without a reply. - func send(_ notification: some NotificationType) - - /// Generate a new request ID to be used in the `send` method that does not take an explicit request ID. - /// - /// These request IDs need to be unique and must not conflict with any request ID that clients might manually specify - /// to `send(_:id:reply:)`. - /// - /// To allow, this request IDs starting with `sk-` are reserved to only be generated by this method and are not - /// allowed to be passed directly to `send(_:id:reply:)`. Thus, generating request IDs prefixed with `sk-` here is - /// safe. Similarly returning UUID-based requests IDs is safe because UUIDs are already unique. - func nextRequestID() -> RequestID - - /// Send a request with a pre-defined request ID and (asynchronously) receive a reply. - /// - /// The request ID must not conflict with any request ID generated by `nextRequestID()`. - func send( - _ request: Request, - id: RequestID, - reply: @escaping @Sendable (LSPResult) -> Void - ) -} - -extension Connection { - /// Send a request and (asynchronously) receive a reply. - public func send( - _ request: Request, - reply: @escaping @Sendable (LSPResult) -> Void - ) -> RequestID { - let id = nextRequestID() - self.send(request, id: id, reply: reply) - return id - } -} - -/// An abstract message handler, such as a language server or client. -public protocol MessageHandler: AnyObject, Sendable { - - /// Handle a notification without a reply. - /// - /// The method should return as soon as the notification has been sufficiently - /// handled to avoid out-of-order requests, e.g. once the notification has - /// been forwarded to clangd. - func handle(_ notification: some NotificationType) - - /// Handle a request and (asynchronously) receive a reply. - /// - /// The method should return as soon as the request has been sufficiently - /// handled to avoid out-of-order requests, e.g. once the corresponding - /// request has been sent to sourcekitd. The actual semantic computation - /// should occur after the method returns and report the result via `reply`. - func handle( - _ request: Request, - id: RequestID, - reply: @Sendable @escaping (LSPResult) -> Void - ) -} - -// MARK: - WeakMessageHelper - -/// Wrapper around a weak `MessageHandler`. -/// -/// This allows us to eg. set the ``TestSourceKitLSPClient`` as the message handler of -/// `SourceKitLSPServer` without retaining it. -public final class WeakMessageHandler: MessageHandler, Sendable { - // `nonisolated(unsafe)` is fine because `handler` is never modified, only if the weak reference is deallocated, which - // is atomic. - private nonisolated(unsafe) weak var handler: (any MessageHandler)? - - public init(_ handler: any MessageHandler) { - self.handler = handler - } - - public func handle(_ params: some NotificationType) { - handler?.handle(params) - } - - public func handle( - _ params: Request, - id: RequestID, - reply: @Sendable @escaping (LSPResult) -> Void - ) { - guard let handler = handler else { - reply(.failure(.unknown("Handler has been deallocated"))) - return - } - handler.handle(params, id: id, reply: reply) - } -} diff --git a/Sources/LanguageServerProtocol/CustomCodable.swift b/Sources/LanguageServerProtocol/CustomCodable.swift deleted file mode 100644 index 8713f4d58..000000000 --- a/Sources/LanguageServerProtocol/CustomCodable.swift +++ /dev/null @@ -1,115 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Property wrapper allowing per-property customization of how the value is -/// encoded/decoded when using Codable. -/// -/// CustomCodable is generic over a `CustomCoder: CustomCodableWrapper`, which -/// wraps the underlying value, and provides the specific Codable implementation. -/// Since each instance of CustomCodable provides its own CustomCoder wrapper, -/// properties of the same type can provide different Codable implementations -/// within the same container. -/// -/// Example: change the encoding of a property `foo` in the following struct to -/// do its encoding through a String instead of the normal Codable implementation. -/// -/// ``` -/// struct MyStruct: Codable { -/// @CustomCodable var foo: Int -/// } -/// -/// struct SillyIntCoding: CustomCodableWrapper { -/// init(from decoder: Decoder) throws { -/// wrappedValue = try Int(decoder.singleValueContainer().decoder(String.self))! -/// } -/// func encode(to encoder: Encoder) throws { -/// try encoder.singleValueContainer().encode("\(wrappedValue)") -/// } -/// var wrappedValue: Int { get } -/// init(wrappedValue: WrappedValue) { self.wrappedValue = wrappedValue } -/// } -/// ``` -@propertyWrapper -public struct CustomCodable { - - public typealias CustomCoder = CustomCoder - - /// The underlying value. - public var wrappedValue: CustomCoder.WrappedValue - - public init(wrappedValue: CustomCoder.WrappedValue) { - self.wrappedValue = wrappedValue - } -} - -extension CustomCodable: Sendable where CustomCoder.WrappedValue: Sendable {} - -extension CustomCodable: Codable { - public init(from decoder: Decoder) throws { - self.wrappedValue = try CustomCoder(from: decoder).wrappedValue - } - - public func encode(to encoder: Encoder) throws { - try CustomCoder(wrappedValue: self.wrappedValue).encode(to: encoder) - } -} - -extension CustomCodable: Equatable where CustomCoder.WrappedValue: Equatable {} -extension CustomCodable: Hashable where CustomCoder.WrappedValue: Hashable {} - -/// Wrapper type providing a Codable implementation for use with `CustomCodable`. -public protocol CustomCodableWrapper: Codable { - - /// The type of the underlying value being wrapped. - associatedtype WrappedValue - - /// The underlying value. - var wrappedValue: WrappedValue { get } - - /// Create a wrapper from an underlying value. - init(wrappedValue: WrappedValue) -} - -extension Optional: CustomCodableWrapper where Wrapped: CustomCodableWrapper { - public var wrappedValue: Wrapped.WrappedValue? { self?.wrappedValue } - public init(wrappedValue: Wrapped.WrappedValue?) { - self = wrappedValue.flatMap { Wrapped.init(wrappedValue: $0) } - } -} - -// The following extensions allow us to encode `CustomCodable>` -// using `encodeIfPresent` (and `decodeIfPresent`) in synthesized `Codable` -// conformances. Without these, we would encode `nil` using `encodeNil` instead -// of skipping the key. - -extension KeyedDecodingContainer { - public func decode( - _ type: CustomCodable.Type, - forKey key: Key - ) throws -> CustomCodable { - CustomCodable(wrappedValue: try decodeIfPresent(T.self, forKey: key)?.wrappedValue) - } -} - -extension KeyedEncodingContainer { - public mutating func encode( - _ value: CustomCodable, - forKey key: Key - ) throws { - try encodeIfPresent( - value.wrappedValue.map { - type(of: value).CustomCoder(wrappedValue: $0) - }, - forKey: key - ) - } -} diff --git a/Sources/LanguageServerProtocol/Error.swift b/Sources/LanguageServerProtocol/Error.swift deleted file mode 100644 index 8a7d026fd..000000000 --- a/Sources/LanguageServerProtocol/Error.swift +++ /dev/null @@ -1,219 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A convenience wrapper for `Result` where the error is a `ResponseError`. -public typealias LSPResult = Swift.Result - -/// Error code suitable for use between language server and client. -public struct ErrorCode: RawRepresentable, Codable, Hashable, Sendable { - - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - // MARK: JSON RPC - public static let parseError: ErrorCode = ErrorCode(rawValue: -32700) - public static let invalidRequest: ErrorCode = ErrorCode(rawValue: -32600) - public static let methodNotFound: ErrorCode = ErrorCode(rawValue: -32601) - public static let invalidParams: ErrorCode = ErrorCode(rawValue: -32602) - public static let internalError: ErrorCode = ErrorCode(rawValue: -32603) - - /// This is the start range of JSON-RPC reserved error codes. - /// It doesn't denote a real error code. No LSP error codes should - /// be defined between the start and end range. For backwards - /// compatibility the `ServerNotInitialized` and the `UnknownErrorCode` - /// are left in the range. - public static let jsonrpcReservedErrorRangeStart = ErrorCode(rawValue: -32099) - public static let serverErrorStart: ErrorCode = jsonrpcReservedErrorRangeStart - - /// Error code indicating that a server received a notification or - /// request before the server has received the `initialize` request. - public static let serverNotInitialized = ErrorCode(rawValue: -32002) - public static let unknownErrorCode = ErrorCode(rawValue: -32001) - - /// This is the end range of JSON-RPC reserved error codes. - /// It doesn't denote a real error code. - public static let jsonrpcReservedErrorRangeEnd = ErrorCode(rawValue: -32000) - /// Deprecated, use jsonrpcReservedErrorRangeEnd - public static let serverErrorEnd = jsonrpcReservedErrorRangeEnd - - /// This is the start range of LSP reserved error codes. - /// It doesn't denote a real error code. - public static let lspReservedErrorRangeStart = ErrorCode(rawValue: -32899) - - /// A request failed but it was syntactically correct, e.g the - /// method name was known and the parameters were valid. The error - /// message should contain human readable information about why - /// the request failed. - public static let requestFailed = ErrorCode(rawValue: -32803) - - /// The server cancelled the request. This error code should - /// only be used for requests that explicitly support being - /// server cancellable. - public static let serverCancelled = ErrorCode(rawValue: -32802) - - /// The server detected that the content of a document got - /// modified outside normal conditions. A server should - /// NOT send this error code if it detects a content change - /// in it unprocessed messages. The result even computed - /// on an older state might still be useful for the client. - /// - /// If a client decides that a result is not of any use anymore - /// the client should cancel the request. - public static let contentModified = ErrorCode(rawValue: -32801) - - /// The client has canceled a request and a server as detected - /// the cancel. - public static let cancelled: ErrorCode = ErrorCode(rawValue: -32800) - - /// This is the end range of LSP reserved error codes. - /// It doesn't denote a real error code. - public static let lspReservedErrorRangeEnd = ErrorCode(rawValue: -32800) - - // MARK: SourceKit-LSP specific error codes - public static let workspaceNotOpen: ErrorCode = ErrorCode(rawValue: -32003) - - /// The method is not implemented in this `LanguageService`. - /// - /// This informs `SourceKitLSPServer` that it should query secondary language services for the results. - public static let requestNotImplemented: ErrorCode = ErrorCode(rawValue: -32004) -} - -/// An error response represented by a code and message. -public struct ResponseError: Error, Codable, Hashable { - public var code: ErrorCode - public var message: String - public var data: LSPAny? - - public init(code: ErrorCode, message: String, data: LSPAny? = nil) { - self.code = code - self.message = message - self.data = data - } -} - -extension ResponseError { - // MARK: Convenience properties for common errors. - - public static let cancelled: ResponseError = ResponseError(code: .cancelled, message: "request cancelled by client") - - public static let serverCancelled: ResponseError = ResponseError( - code: .serverCancelled, - message: "request cancelled by server" - ) - - public static func workspaceNotOpen(_ uri: DocumentURI) -> ResponseError { - return ResponseError(code: .workspaceNotOpen, message: "No workspace containing '\(uri)' found") - } - - public static func invalidParams(_ message: String) -> ResponseError { - return ResponseError(code: .invalidParams, message: message) - } - - public static func methodNotFound(_ method: String) -> ResponseError { - return ResponseError(code: .methodNotFound, message: "method not found: \(method)") - } - - public static func unknown(_ message: String) -> ResponseError { - return ResponseError(code: .unknownErrorCode, message: message) - } - - public static func requestFailed(_ message: String) -> ResponseError { - return ResponseError(code: .requestFailed, message: message) - } - - public static func internalError(_ message: String) -> ResponseError { - return ResponseError(code: .internalError, message: message) - } - - public static func requestNotImplemented(_ method: any RequestType.Type) -> ResponseError { - return ResponseError(code: .requestNotImplemented, message: "request not implemented: \(method.method)") - } -} - -/// An error during message decoding. -public struct MessageDecodingError: Error, Hashable { - - /// The error code. - public var code: ErrorCode - - /// A free-form description of the error. - public var message: String - - /// If it was possible to recover the request id, it is stored here. This can be used e.g. to reply with a `ResponseError` to invalid requests. - public var id: RequestID? - - @frozen public enum MessageKind: Sendable { - case request - case response - case notification - case unknown - } - - /// What kind of message was being decoded, or `.unknown`. - public var messageKind: MessageKind - - public init(code: ErrorCode, message: String, id: RequestID? = nil, messageKind: MessageKind = .unknown) { - self.code = code - self.message = message - self.id = id - self.messageKind = messageKind - } -} - -extension MessageDecodingError { - public static func methodNotFound( - _ method: String, - id: RequestID? = nil, - messageKind: MessageKind = .unknown - ) -> MessageDecodingError { - return MessageDecodingError( - code: .methodNotFound, - message: "method not found: \(method)", - id: id, - messageKind: messageKind - ) - } - - public static func invalidRequest( - _ reason: String, - id: RequestID? = nil, - messageKind: MessageKind = .unknown - ) -> MessageDecodingError { - return MessageDecodingError(code: .invalidRequest, message: reason, id: id, messageKind: messageKind) - } - - public static func invalidParams( - _ reason: String, - id: RequestID? = nil, - messageKind: MessageKind = .unknown - ) -> MessageDecodingError { - return MessageDecodingError(code: .invalidParams, message: reason, id: id, messageKind: messageKind) - } - - public static func parseError( - _ reason: String, - id: RequestID? = nil, - messageKind: MessageKind = .unknown - ) -> MessageDecodingError { - return MessageDecodingError(code: .parseError, message: reason, id: id, messageKind: messageKind) - } -} - -extension ResponseError { - /// Converts a `MessageDecodingError` to a `ResponseError`. - public init(_ decodingError: MessageDecodingError) { - self.init(code: decodingError.code, message: decodingError.message) - } -} diff --git a/Sources/LanguageServerProtocol/Message.swift b/Sources/LanguageServerProtocol/Message.swift deleted file mode 100644 index 97c1d5972..000000000 --- a/Sources/LanguageServerProtocol/Message.swift +++ /dev/null @@ -1,76 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public protocol MessageType: Codable, Sendable {} - -/// `RequestType` with no associated type or same-type requirements. Most users should prefer -/// `RequestType`. -public protocol _RequestType: MessageType { - - /// The name of the request. - static var method: String { get } - - /// *Implementation detail*. Dispatch `self` to the given handler and reply on `connection`. - /// Only needs to be declared as a protocol requirement of `_RequestType` so we can call the implementation on `RequestType` from the underscored type. - func _handle( - _ handler: MessageHandler, - id: RequestID, - reply: @Sendable @escaping (LSPResult, RequestID) -> Void - ) -} - -/// A request, which must have a unique `method` name as well as an associated response type. -public protocol RequestType: _RequestType { - - /// The type of of the response to this request. - associatedtype Response: ResponseType -} - -/// A notification, which must have a unique `method` name. -public protocol NotificationType: MessageType { - - /// The name of the request. - static var method: String { get } -} - -/// A response. -public protocol ResponseType: MessageType {} - -extension RequestType { - public func _handle( - _ handler: MessageHandler, - id: RequestID, - reply: @Sendable @escaping (LSPResult, RequestID) -> Void - ) { - handler.handle(self, id: id) { response in - reply(response.map({ $0 as ResponseType }), id) - } - } -} - -extension NotificationType { - public func _handle(_ handler: MessageHandler) { - handler.handle(self) - } -} - -/// A `textDocument/*` notification, which takes a text document identifier -/// indicating which document it operates in or on. -public protocol TextDocumentNotification: NotificationType { - var textDocument: TextDocumentIdentifier { get } -} - -/// A `textDocument/*` request, which takes a text document identifier -/// indicating which document it operates in or on. -public protocol TextDocumentRequest: RequestType { - var textDocument: TextDocumentIdentifier { get } -} diff --git a/Sources/LanguageServerProtocol/MessageRegistry.swift b/Sources/LanguageServerProtocol/MessageRegistry.swift deleted file mode 100644 index 114ae9528..000000000 --- a/Sources/LanguageServerProtocol/MessageRegistry.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public final class MessageRegistry: Sendable { - - public static let lspProtocol: MessageRegistry = - MessageRegistry(requests: builtinRequests, notifications: builtinNotifications) - - private let methodToRequest: [String: _RequestType.Type] - private let methodToNotification: [String: NotificationType.Type] - - public init(requests: [_RequestType.Type], notifications: [NotificationType.Type]) { - self.methodToRequest = Dictionary(uniqueKeysWithValues: requests.map { ($0.method, $0) }) - self.methodToNotification = Dictionary(uniqueKeysWithValues: notifications.map { ($0.method, $0) }) - } - - /// Returns the type of the message named `method`, or nil if it is unknown. - public func requestType(for method: String) -> _RequestType.Type? { - return methodToRequest[method] - } - - /// Returns the type of the message named `method`, or nil if it is unknown. - public func notificationType(for method: String) -> NotificationType.Type? { - return methodToNotification[method] - } - -} diff --git a/Sources/LanguageServerProtocol/Messages.swift b/Sources/LanguageServerProtocol/Messages.swift deleted file mode 100644 index 6318d6a08..000000000 --- a/Sources/LanguageServerProtocol/Messages.swift +++ /dev/null @@ -1,140 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The set of known requests. -/// -/// All requests from LSP as well as any extensions provided by the server should be listed here. -/// If you are adding a message for testing only, you can register it dynamically using -/// `MessageRegistry._register()` which allows you to avoid bloating the real server implementation. -public let builtinRequests: [_RequestType.Type] = [ - ApplyEditRequest.self, - CallHierarchyIncomingCallsRequest.self, - CallHierarchyOutgoingCallsRequest.self, - CallHierarchyPrepareRequest.self, - CodeActionRequest.self, - CodeActionResolveRequest.self, - CodeLensRefreshRequest.self, - CodeLensRequest.self, - CodeLensResolveRequest.self, - ColorPresentationRequest.self, - CompletionItemResolveRequest.self, - CompletionRequest.self, - CreateWorkDoneProgressRequest.self, - DeclarationRequest.self, - DefinitionRequest.self, - DiagnosticsRefreshRequest.self, - DoccDocumentationRequest.self, - DocumentColorRequest.self, - DocumentDiagnosticsRequest.self, - DocumentFormattingRequest.self, - DocumentHighlightRequest.self, - DocumentLinkRequest.self, - DocumentLinkResolveRequest.self, - DocumentOnTypeFormattingRequest.self, - DocumentRangeFormattingRequest.self, - DocumentSemanticTokensDeltaRequest.self, - DocumentSemanticTokensRangeRequest.self, - DocumentSemanticTokensRequest.self, - DocumentSymbolRequest.self, - DocumentTestsRequest.self, - ExecuteCommandRequest.self, - FoldingRangeRequest.self, - GetReferenceDocumentRequest.self, - HoverRequest.self, - ImplementationRequest.self, - InitializeRequest.self, - InlayHintRefreshRequest.self, - InlayHintRequest.self, - InlayHintResolveRequest.self, - InlineValueRefreshRequest.self, - InlineValueRequest.self, - IsIndexingRequest.self, - LinkedEditingRangeRequest.self, - MonikersRequest.self, - OutputPathsRequest.self, - PeekDocumentsRequest.self, - SynchronizeRequest.self, - PrepareRenameRequest.self, - ReferencesRequest.self, - RegisterCapabilityRequest.self, - RenameRequest.self, - SelectionRangeRequest.self, - SetOptionsRequest.self, - ShowDocumentRequest.self, - ShowMessageRequest.self, - ShutdownRequest.self, - SignatureHelpRequest.self, - SourceKitOptionsRequest.self, - SymbolInfoRequest.self, - TriggerReindexRequest.self, - TypeDefinitionRequest.self, - TypeHierarchyPrepareRequest.self, - TypeHierarchySubtypesRequest.self, - TypeHierarchySupertypesRequest.self, - UnregisterCapabilityRequest.self, - WillCreateFilesRequest.self, - WillDeleteFilesRequest.self, - WillRenameFilesRequest.self, - WillSaveWaitUntilTextDocumentRequest.self, - WorkspaceDiagnosticsRequest.self, - WorkspaceFoldersRequest.self, - WorkspaceSemanticTokensRefreshRequest.self, - WorkspaceSymbolResolveRequest.self, - WorkspaceSymbolsRequest.self, - WorkspaceTestsRequest.self, -] - -/// The set of known notifications. -/// -/// All notifications from LSP as well as any extensions provided by the server should be listed -/// here. If you are adding a message for testing only, you can register it dynamically using -/// `MessageRegistry._register()` which allows you to avoid bloating the real server implementation. -public let builtinNotifications: [NotificationType.Type] = [ - CancelRequestNotification.self, - CancelWorkDoneProgressNotification.self, - DidChangeActiveDocumentNotification.self, - DidChangeConfigurationNotification.self, - DidChangeNotebookDocumentNotification.self, - DidChangeTextDocumentNotification.self, - DidChangeWatchedFilesNotification.self, - DidChangeWorkspaceFoldersNotification.self, - DidCloseNotebookDocumentNotification.self, - DidCloseTextDocumentNotification.self, - DidCreateFilesNotification.self, - DidDeleteFilesNotification.self, - DidOpenNotebookDocumentNotification.self, - DidOpenTextDocumentNotification.self, - DidRenameFilesNotification.self, - DidSaveNotebookDocumentNotification.self, - DidSaveTextDocumentNotification.self, - ExitNotification.self, - InitializedNotification.self, - LogMessageNotification.self, - LogTraceNotification.self, - PublishDiagnosticsNotification.self, - SetTraceNotification.self, - ShowMessageNotification.self, - WillSaveTextDocumentNotification.self, - WorkDoneProgress.self, -] - -// MARK: Miscellaneous Message Types - -public struct VoidResponse: ResponseType, Hashable { - public init() {} -} - -extension Optional: MessageType where Wrapped: MessageType {} -extension Optional: ResponseType where Wrapped: ResponseType {} - -extension Array: MessageType where Element: MessageType {} -extension Array: ResponseType where Element: ResponseType {} diff --git a/Sources/LanguageServerProtocol/Notifications/CancelRequestNotification.swift b/Sources/LanguageServerProtocol/Notifications/CancelRequestNotification.swift deleted file mode 100644 index e6e4f22a3..000000000 --- a/Sources/LanguageServerProtocol/Notifications/CancelRequestNotification.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification that the given request (previously made) should be cancelled, if possible. -/// -/// Cancellation is not guaranteed and the underlying request may finish normally. If the request is -/// successfully cancelled, it should return the `.cancelled` error code. -/// -/// As with any `$` requests, the server is free to ignore this notification. -/// -/// - Parameter id: The request to cancel. -public struct CancelRequestNotification: NotificationType, Hashable { - public static let method: String = "$/cancelRequest" - - /// The request to cancel. - public var id: RequestID - - public init(id: RequestID) { - self.id = id - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/CancelWorkDoneProgressNotification.swift b/Sources/LanguageServerProtocol/Notifications/CancelWorkDoneProgressNotification.swift deleted file mode 100644 index 5d2d9d86f..000000000 --- a/Sources/LanguageServerProtocol/Notifications/CancelWorkDoneProgressNotification.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct CancelWorkDoneProgressNotification: NotificationType { - public static let method: String = "window/workDoneProgress/cancel" - - public var token: ProgressToken - - public init(token: ProgressToken) { - self.token = token - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/ConfigurationNotification.swift b/Sources/LanguageServerProtocol/Notifications/ConfigurationNotification.swift deleted file mode 100644 index 8de9bbb6a..000000000 --- a/Sources/LanguageServerProtocol/Notifications/ConfigurationNotification.swift +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the client that the configuration of the workspace has changed. -/// -/// - Note: the format of the settings is implementation-defined. -/// -/// - Parameter settings: The changed workspace settings. -public struct DidChangeConfigurationNotification: NotificationType { - public static let method: String = "workspace/didChangeConfiguration" - - /// The changed workspace settings. - public var settings: WorkspaceSettingsChange - - public init(settings: WorkspaceSettingsChange) { - self.settings = settings - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/DidChangeActiveDocumentNotification.swift b/Sources/LanguageServerProtocol/Notifications/DidChangeActiveDocumentNotification.swift deleted file mode 100644 index 1227b1606..000000000 --- a/Sources/LanguageServerProtocol/Notifications/DidChangeActiveDocumentNotification.swift +++ /dev/null @@ -1,23 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DidChangeActiveDocumentNotification: NotificationType { - public static let method: String = "window/didChangeActiveDocument" - - /// The document that is being displayed in the active editor or `null` to indicate that either no document is active - /// or that the currently open document is not handled by SourceKit-LSP. - public var textDocument: TextDocumentIdentifier? - - public init(textDocument: TextDocumentIdentifier?) { - self.textDocument = textDocument - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/DidChangeFileNotifications.swift b/Sources/LanguageServerProtocol/Notifications/DidChangeFileNotifications.swift deleted file mode 100644 index d22c6a6d3..000000000 --- a/Sources/LanguageServerProtocol/Notifications/DidChangeFileNotifications.swift +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DidCreateFilesNotification: NotificationType { - public static let method: String = "workspace/didCreateFiles" - - /// An array of all files/folders created in this operation. - public var files: [FileCreate] - - public init(files: [FileCreate]) { - self.files = files - } -} - -public struct DidRenameFilesNotification: NotificationType { - public static let method: String = "workspace/didRenameFiles" - - /// An array of all files/folders renamed in this operation. When a folder - /// is renamed, only the folder will be included, and not its children. - public var files: [FileRename] - - public init(files: [FileRename]) { - self.files = files - } -} - -public struct DidDeleteFilesNotification: NotificationType { - public static let method: String = "workspace/didDeleteFiles" - - /// An array of all files/folders created in this operation. - public var files: [FileDelete] - - public init(files: [FileDelete]) { - self.files = files - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/DidChangeWatchedFilesNotification.swift b/Sources/LanguageServerProtocol/Notifications/DidChangeWatchedFilesNotification.swift deleted file mode 100644 index 72fdd247a..000000000 --- a/Sources/LanguageServerProtocol/Notifications/DidChangeWatchedFilesNotification.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the client when changes to watched files are detected. -/// -/// - Parameter changes: The set of file changes. -public struct DidChangeWatchedFilesNotification: NotificationType { - public static let method: String = "workspace/didChangeWatchedFiles" - - /// The file changes. - public var changes: [FileEvent] - - public init(changes: [FileEvent]) { - self.changes = changes - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/DidChangeWorkspaceFoldersNotification.swift b/Sources/LanguageServerProtocol/Notifications/DidChangeWorkspaceFoldersNotification.swift deleted file mode 100644 index b8b9a9c50..000000000 --- a/Sources/LanguageServerProtocol/Notifications/DidChangeWorkspaceFoldersNotification.swift +++ /dev/null @@ -1,42 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the client that the set of open workspace folders has changed. -/// -/// - Parameter event: The set of changes. -/// -/// Requires the `workspaceFolders` capability on both the client and server. -public struct DidChangeWorkspaceFoldersNotification: NotificationType { - public static let method: String = "workspace/didChangeWorkspaceFolders" - - /// The set of changes. - public var event: WorkspaceFoldersChangeEvent - - public init(event: WorkspaceFoldersChangeEvent) { - self.event = event - } -} - -/// The workspace folder change event. -public struct WorkspaceFoldersChangeEvent: Codable, Hashable, Sendable { - - /// The array of added workspace folders - public var added: [WorkspaceFolder]? - - /// The array of the removed workspace folders - public var removed: [WorkspaceFolder]? - - public init(added: [WorkspaceFolder]? = nil, removed: [WorkspaceFolder]? = nil) { - self.added = added - self.removed = removed - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/ExitNotification.swift b/Sources/LanguageServerProtocol/Notifications/ExitNotification.swift deleted file mode 100644 index e47e7b5f4..000000000 --- a/Sources/LanguageServerProtocol/Notifications/ExitNotification.swift +++ /dev/null @@ -1,19 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification that the server process should exit. -/// -/// This notification will come after the shutdown request finishes. -public struct ExitNotification: NotificationType, Hashable { - public static let method: String = "exit" - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Notifications/InitializedNotification.swift b/Sources/LanguageServerProtocol/Notifications/InitializedNotification.swift deleted file mode 100644 index d8bf05e7c..000000000 --- a/Sources/LanguageServerProtocol/Notifications/InitializedNotification.swift +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the client that its own initialization of the language server has finished. -public struct InitializedNotification: NotificationType, Hashable { - public static let method: String = "initialized" - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Notifications/LogMessageNotification.swift b/Sources/LanguageServerProtocol/Notifications/LogMessageNotification.swift deleted file mode 100644 index eee2f4660..000000000 --- a/Sources/LanguageServerProtocol/Notifications/LogMessageNotification.swift +++ /dev/null @@ -1,199 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the server containing a log message. -/// -/// - Parameters: -/// - type: The kind of log message. -/// - message: The contents of the message. -public struct LogMessageNotification: NotificationType, Hashable { - public static let method: String = "window/logMessage" - - /// The kind of log message. - public var type: WindowMessageType - - /// The contents of the message. - public var message: String - - /// If specified, the client should log the message to a log with this name instead of the standard log for this LSP - /// server. - /// - /// **(LSP Extension)** - public var logName: String? - - /// If specified, allows grouping log messages that belong to the same originating task together, instead of logging - /// them in chronological order in which they were produced. - /// - /// **(LSP Extension)** guarded by the experimental `structured-logs` feature. - public var structure: StructuredLogKind? - - public init(type: WindowMessageType, message: String, logName: String? = nil, structure: StructuredLogKind? = nil) { - self.type = type - self.message = message - self.logName = logName - self.structure = structure - } -} - -public enum StructuredLogKind: Codable, Hashable, Sendable { - case begin(StructuredLogBegin) - case report(StructuredLogReport) - case end(StructuredLogEnd) - - public var taskID: String { - switch self { - case .begin(let begin): return begin.taskID - case .report(let report): return report.taskID - case .end(let end): return end.taskID - } - } - - public init(from decoder: Decoder) throws { - if let begin = try? StructuredLogBegin(from: decoder) { - self = .begin(begin) - } else if let report = try? StructuredLogReport(from: decoder) { - self = .report(report) - } else if let end = try? StructuredLogEnd(from: decoder) { - self = .end(end) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected StructuredLogBegin, StructuredLogReport, or StructuredLogEnd" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .begin(let begin): - try begin.encode(to: encoder) - case .report(let report): - try report.encode(to: encoder) - case .end(let end): - try end.encode(to: encoder) - } - } -} - -/// Indicates the beginning of a new task that may receive updates with `StructuredLogReport` or `StructuredLogEnd` -/// payloads. -public struct StructuredLogBegin: Codable, Hashable, Sendable { - /// A succinct title that can be used to describe the task that started this structured. - public var title: String - - /// A unique identifier, identifying the task this structured log message belongs to. - public var taskID: String - - private enum CodingKeys: CodingKey { - case kind - case title - case taskID - } - - public init(title: String, taskID: String) { - self.title = title - self.taskID = taskID - } - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "begin" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogBegin is not 'begin'" - ) - } - - self.title = try container.decode(String.self, forKey: .title) - self.taskID = try container.decode(String.self, forKey: .taskID) - - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("begin", forKey: .kind) - try container.encode(self.title, forKey: .title) - try container.encode(self.taskID, forKey: .taskID) - } -} - -/// Adds a new log message to a structured log without ending it. -public struct StructuredLogReport: Codable, Hashable, Sendable { - /// A unique identifier, identifying the task this structured log message belongs to. - public var taskID: String - - private enum CodingKeys: CodingKey { - case kind - case taskID - } - - public init(taskID: String) { - self.taskID = taskID - } - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "report" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogReport is not 'report'" - ) - } - - self.taskID = try container.decode(String.self, forKey: .taskID) - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("report", forKey: .kind) - try container.encode(self.taskID, forKey: .taskID) - } -} - -/// Ends a structured log. No more `StructuredLogReport` updates should be sent for this task ID. -/// -/// The task ID may be re-used for new structured logs by beginning a new structured log for that task. -public struct StructuredLogEnd: Codable, Hashable, Sendable { - /// A unique identifier, identifying the task this structured log message belongs to. - public var taskID: String - - private enum CodingKeys: CodingKey { - case kind - case taskID - } - - public init(taskID: String) { - self.taskID = taskID - } - - public init(from decoder: any Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - guard try container.decode(String.self, forKey: .kind) == "end" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of StructuredLogEnd is not 'end'" - ) - } - - self.taskID = try container.decode(String.self, forKey: .taskID) - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("end", forKey: .kind) - try container.encode(self.taskID, forKey: .taskID) - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/LogTraceNotification.swift b/Sources/LanguageServerProtocol/Notifications/LogTraceNotification.swift deleted file mode 100644 index 2027703f5..000000000 --- a/Sources/LanguageServerProtocol/Notifications/LogTraceNotification.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A notification to log the trace of the server’s execution. The amount and content of these notifications depends on the current trace configuration. If trace is 'off', the server should not send any logTrace notification. If trace is 'messages', the server should not add the 'verbose' field in the LogTraceParams. -/// -/// $/logTrace should be used for systematic trace reporting. For single debugging messages, the server should send window/logMessage notifications. -public struct LogTraceNotification: NotificationType, Hashable, Codable { - public static let method: String = "$/logTrace" - - /// The message to be logged. - public var message: String - - /// Additional information that can be computed if the `trace` configuration - /// is set to `'verbose'` - public var verbose: String? - - public init(message: String, verbose: String?) { - self.message = message - self.verbose = verbose - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/PublishDiagnosticsNotification.swift b/Sources/LanguageServerProtocol/Notifications/PublishDiagnosticsNotification.swift deleted file mode 100644 index 1d41be0ba..000000000 --- a/Sources/LanguageServerProtocol/Notifications/PublishDiagnosticsNotification.swift +++ /dev/null @@ -1,44 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the server containing any diagnostics to show in a given document. -/// -/// The publishDiagnostics notification provides the complete set of diagnostics and must be sent -/// whenever the set of active diagnostics change. For example, if a `didChange` notification from -/// the client fixes all of the existing errors, there should be a `publishDiagnostics` notification -/// with an empty `diagnostics = []`. -/// -/// There is no guarantee about _when_ the `publishDiagnostics` notification will be sent, and the -/// server is free to not send a notification unless the set of diagnostics has actually changed, or -/// to coalesce the notification across multiple changes in a short period of time. -/// -/// - Parameters: -/// - uri: The document in which the diagnostics should be shown. -/// - diagnostics: The complete list of diagnostics in the document, if any. -public struct PublishDiagnosticsNotification: NotificationType, Hashable, Codable { - public static let method: String = "textDocument/publishDiagnostics" - - /// The document in which the diagnostics should be shown. - public var uri: DocumentURI - - /// Optional the version number of the document the diagnostics are published for. - public var version: Int? - - /// The complete list of diagnostics in the document, if any. - public var diagnostics: [Diagnostic] - - public init(uri: DocumentURI, version: Int? = nil, diagnostics: [Diagnostic]) { - self.uri = uri - self.version = version - self.diagnostics = diagnostics - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/ReopenTextDocumentNotifications.swift b/Sources/LanguageServerProtocol/Notifications/ReopenTextDocumentNotifications.swift deleted file mode 100644 index fb1f8a8a1..000000000 --- a/Sources/LanguageServerProtocol/Notifications/ReopenTextDocumentNotifications.swift +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Re-open the given document, discarding any in-memory state. -/// -/// This notification is designed to be used internally in SourceKit-LSP: When build setting have changed, we re-open -/// the document in sourcekitd to re-build its AST. This needs to be handled via a notification to ensure that no other -/// request for this document is executing at the same time. -/// -/// **(LSP Extension)** -public struct ReopenTextDocumentNotification: NotificationType, Hashable { - public static let method: String = "textDocument/reopen" - - /// The document identifier and initial contents. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/SetTraceNotification.swift b/Sources/LanguageServerProtocol/Notifications/SetTraceNotification.swift deleted file mode 100644 index 0f49bddd3..000000000 --- a/Sources/LanguageServerProtocol/Notifications/SetTraceNotification.swift +++ /dev/null @@ -1,23 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A notification that should be used by the client to modify the trace setting of the server. -public struct SetTraceNotification: NotificationType, Hashable, Codable { - public static let method: String = "$/setTrace" - - /// The new value that should be assigned to the trace setting. - public var value: Tracing - - public init(value: Tracing) { - self.value = value - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/ShowMessageNotification.swift b/Sources/LanguageServerProtocol/Notifications/ShowMessageNotification.swift deleted file mode 100644 index 8c6b58c08..000000000 --- a/Sources/LanguageServerProtocol/Notifications/ShowMessageNotification.swift +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the server containing a message for the client to display. -/// -/// - Parameters: -/// - type: The kind of message. -/// - message: The contents of the message. -public struct ShowMessageNotification: NotificationType, Hashable { - public static let method: String = "window/showMessage" - - /// The kind of message. - public var type: WindowMessageType - - /// The contents of the message. - public var message: String - - public init(type: WindowMessageType, message: String) { - self.type = type - self.message = message - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/TextSynchronizationNotifications.swift b/Sources/LanguageServerProtocol/Notifications/TextSynchronizationNotifications.swift deleted file mode 100644 index b5917aaa5..000000000 --- a/Sources/LanguageServerProtocol/Notifications/TextSynchronizationNotifications.swift +++ /dev/null @@ -1,224 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Notification from the client that a new document is open and its content should be managed by -/// the text synchronization notifications until it has been closed. -/// -/// The `didOpen` notification provides the initial contents of the document. Thereafter, any -/// queries that need the content of this document should use the contents provided here (or updated -/// via subsequent `didChange` notifications) and should ignore the contents on disk. -/// -/// An open document can be modified using the `didChange` notification, and when done closed using -/// the `didClose` notification. Once closed, the server can use the contents on disk, if needed. -/// A document can only be opened once at a time, and must be balanced by a `didClose` before being -/// opened again. -/// -/// Servers that provide document synchronization should set the `textDocumentSync` server -/// capability. -/// -/// - Parameter textDocument: The document identifier and initial contents. -public struct DidOpenTextDocumentNotification: NotificationType, Hashable { - public static let method: String = "textDocument/didOpen" - - /// The document identifier and initial contents. - public var textDocument: TextDocumentItem - - public init(textDocument: TextDocumentItem) { - self.textDocument = textDocument - } -} - -/// Notification that the given document is closed and no longer managed by the text synchronization -/// notifications. -/// -/// The document must have previously been opened with `didOpen`. Closing the document returns -/// management of the document contents to disk, if appropriate. -/// -/// - Parameter textDocument: The document to close, which must be currently open. -public struct DidCloseTextDocumentNotification: NotificationType, Hashable { - public static let method: String = "textDocument/didClose" - - /// The document to close, which must be currently open. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -/// Notification that the contents of the given document have been changed. -/// -/// Updates the content of a document previously opened with `didOpen` by applying a list of -/// changes, which may either be full document replacements, or incremental edits. -/// -/// Servers that support incremental edits should set the `change` text document sync option. -/// -/// - Parameters: -/// - textDocument: The document to change and its current version identifier. -/// - contentChanges: Edits to the document. -public struct DidChangeTextDocumentNotification: NotificationType, Hashable { - public static let method: String = "textDocument/didChange" - - /// The document that did change. The version number points - /// to the version after all provided content changes have - /// been applied. - public var textDocument: VersionedTextDocumentIdentifier - - /// The actual content changes. The content changes describe single state - /// changes to the document. So if there are two content changes c1 (at - /// array index 0) and c2 (at array index 1) for a document in state S then - /// c1 moves the document from S to S' and c2 from S' to S''. So c1 is - /// computed on the state S and c2 is computed on the state S'. - /// - /// To mirror the content of a document using change events use the following - /// approach: - /// - start with the same initial content - /// - apply the 'textDocument/didChange' notifications in the order you - /// receive them. - /// - apply the `TextDocumentContentChangeEvent`s in a single notification - /// in the order you receive them. - public var contentChanges: [TextDocumentContentChangeEvent] - - /// Force the LSP to rebuild its AST for the given file. This is useful for clangd to workaround clangd's assumption that - /// missing header files will stay missing. - /// **LSP Extension from clangd**. - public var forceRebuild: Bool? = nil - - public init( - textDocument: VersionedTextDocumentIdentifier, - contentChanges: [TextDocumentContentChangeEvent], - forceRebuild: Bool? = nil - ) { - self.textDocument = textDocument - self.contentChanges = contentChanges - self.forceRebuild = forceRebuild - } -} - -/// Notification that the given document will be saved. -/// -/// - Parameters: -/// - textDocument: The document that will be saved. -/// - reason: Whether this was user-initiated, auto-saved, etc. -/// -/// Servers that support willSave should set the `willSave` text document sync option. -public struct WillSaveTextDocumentNotification: TextDocumentNotification, Hashable { - public static let method: String = "textDocument/willSave" - - /// The document that will be saved. - public var textDocument: TextDocumentIdentifier - - /// Whether this is user-initiated save, auto-saved, etc. - public var reason: TextDocumentSaveReason - - public init(textDocument: TextDocumentIdentifier, reason: TextDocumentSaveReason) { - self.textDocument = textDocument - self.reason = reason - } -} - -/// Notification that the given document was saved. -/// -/// - Parameters: -/// - textDocument: The document that was saved. -/// - text: The content of the document at the time of save. -/// -/// Servers that support didSave should set the `save` text document sync option. -public struct DidSaveTextDocumentNotification: TextDocumentNotification, Hashable { - public static let method: String = "textDocument/didSave" - - /// The document that was saved. - public var textDocument: TextDocumentIdentifier - - /// The content of the document at the time of save. - /// - /// Only provided if the server specified `includeText == true`. - public var text: String? - - public init(textDocument: TextDocumentIdentifier, text: String? = nil) { - self.textDocument = textDocument - self.text = text - } -} - -/// The open notification is sent from the client to the server when a notebook document is opened. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability. -public struct DidOpenNotebookDocumentNotification: NotificationType, Hashable { - public static let method: String = "notebookDocument/didOpen" - - /// The notebook document that got opened. - public var notebookDocument: NotebookDocument - - /// The text documents that represent the content - /// of a notebook cell. - public var cellTextDocuments: [TextDocumentItem] - - public init(notebookDocument: NotebookDocument, cellTextDocuments: [TextDocumentItem]) { - self.notebookDocument = notebookDocument - self.cellTextDocuments = cellTextDocuments - } -} - -/// The change notification is sent from the client to the server when a notebook document changes. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability. -public struct DidChangeNotebookDocumentNotification: NotificationType, Hashable { - public static let method: String = "notebookDocument/didChange" - - /// The notebook document that did change. The version number points - /// to the version after all provided changes have been applied. - public var notebookDocument: VersionedNotebookDocumentIdentifier - - /// The actual changes to the notebook document. - /// - /// The change describes single state change to the notebook document. - /// So it moves a notebook document, its cells and its cell text document - /// contents from state S to S'. - /// - /// To mirror the content of a notebook using change events use the - /// following approach: - /// - start with the same initial content - /// - apply the 'notebookDocument/didChange' notifications in the order - /// you receive them. - public var change: NotebookDocumentChangeEvent - - public init(notebookDocument: VersionedNotebookDocumentIdentifier, change: NotebookDocumentChangeEvent) { - self.notebookDocument = notebookDocument - self.change = change - } -} - -/// The save notification is sent from the client to the server when a notebook document is saved. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability. -public struct DidSaveNotebookDocumentNotification: NotificationType { - public static let method: String = "notebookDocument/didSave" - - /// The notebook document that got saved. - public var notebookDocument: NotebookDocumentIdentifier - - public init(notebookDocument: NotebookDocumentIdentifier) { - self.notebookDocument = notebookDocument - } -} - -/// The close notification is sent from the client to the server when a notebook document is closed. It is only sent by a client if the server requested the synchronization mode `notebook` in its `notebookDocumentSync` capability. -public struct DidCloseNotebookDocumentNotification: NotificationType { - public static let method: String = "notebookDocument/didClose" - - /// The notebook document that got closed. - public var notebookDocument: NotebookDocumentIdentifier - - /// The text documents that represent the content - /// of a notebook cell that got closed. - public var cellTextDocuments: [TextDocumentIdentifier] - - public init(notebookDocument: NotebookDocumentIdentifier, cellTextDocuments: [TextDocumentIdentifier]) { - self.notebookDocument = notebookDocument - self.cellTextDocuments = cellTextDocuments - } -} diff --git a/Sources/LanguageServerProtocol/Notifications/WorkDoneProgress.swift b/Sources/LanguageServerProtocol/Notifications/WorkDoneProgress.swift deleted file mode 100644 index 3bfeb254a..000000000 --- a/Sources/LanguageServerProtocol/Notifications/WorkDoneProgress.swift +++ /dev/null @@ -1,224 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct WorkDoneProgress: NotificationType, Hashable { - public static let method: String = "$/progress" - - /// The progress token provided by the client or server. - public var token: ProgressToken - - /// The progress data. - public var value: WorkDoneProgressKind - - public init(token: ProgressToken, value: WorkDoneProgressKind) { - self.token = token - self.value = value - } -} - -public enum WorkDoneProgressKind: Codable, Hashable, Sendable { - case begin(WorkDoneProgressBegin) - case report(WorkDoneProgressReport) - case end(WorkDoneProgressEnd) - - public init(from decoder: Decoder) throws { - if let begin = try? WorkDoneProgressBegin(from: decoder) { - self = .begin(begin) - } else if let report = try? WorkDoneProgressReport(from: decoder) { - self = .report(report) - } else if let end = try? WorkDoneProgressEnd(from: decoder) { - self = .end(end) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected WorkDoneProgressBegin, WorkDoneProgressReport, or WorkDoneProgressEnd" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .begin(let begin): - try begin.encode(to: encoder) - case .report(let report): - try report.encode(to: encoder) - case .end(let end): - try end.encode(to: encoder) - } - } -} - -public struct WorkDoneProgressBegin: Codable, Hashable, Sendable { - /// Mandatory title of the progress operation. Used to briefly inform about - /// the kind of operation being performed. - /// - /// Examples: "Indexing" or "Linking dependencies". - public var title: String - - /// Controls if a cancel button should show to allow the user to cancel the - /// long running operation. Clients that don't support cancellation are - /// allowed to ignore the setting. - public var cancellable: Bool? - - /// Optional, more detailed associated progress message. Contains - /// complementary information to the `title`. - /// - /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". - /// If unset, the previous progress message (if any) is still valid. - public var message: String? - - /// Optional progress percentage to display (value 100 is considered 100%). - /// If not provided infinite progress is assumed and clients are allowed - /// to ignore the `percentage` value in subsequent in report notifications. - /// - /// The value should be steadily rising. Clients are free to ignore values - /// that are not following this rule. The value range is [0, 100] - public var percentage: Int? - - public init(title: String, cancellable: Bool? = nil, message: String? = nil, percentage: Int? = nil) { - self.title = title - self.cancellable = cancellable - self.message = message - self.percentage = percentage - } - - enum CodingKeys: CodingKey { - case kind - case title - case cancellable - case message - case percentage - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "begin" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of WorkDoneProgressBegin is not 'begin'" - ) - } - - self.title = try container.decode(String.self, forKey: .title) - self.cancellable = try container.decodeIfPresent(Bool.self, forKey: .cancellable) - self.message = try container.decodeIfPresent(String.self, forKey: .message) - self.percentage = try container.decodeIfPresent(Int.self, forKey: .percentage) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("begin", forKey: .kind) - try container.encode(self.title, forKey: .title) - try container.encodeIfPresent(self.cancellable, forKey: .cancellable) - try container.encodeIfPresent(self.message, forKey: .message) - try container.encodeIfPresent(self.percentage, forKey: .percentage) - } -} - -public struct WorkDoneProgressReport: Codable, Hashable, Sendable { - /// Controls enablement state of a cancel button. This property is only valid - /// if a cancel button got requested in the `WorkDoneProgressBegin` payload. - /// - /// Clients that don't support cancellation or don't support control the - /// button's enablement state are allowed to ignore the setting. - public var cancellable: Bool? - - /// Optional, more detailed associated progress message. Contains - /// complementary information to the `title`. - /// - /// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". - /// If unset, the previous progress message (if any) is still valid. - public var message: String? - - /// Optional progress percentage to display (value 100 is considered 100%). - /// If not provided infinite progress is assumed and clients are allowed - /// to ignore the `percentage` value in subsequent in report notifications. - /// - /// The value should be steadily rising. Clients are free to ignore values - /// that are not following this rule. The value range is [0, 100] - public var percentage: Int? - - public init(cancellable: Bool? = nil, message: String? = nil, percentage: Int? = nil) { - self.cancellable = cancellable - self.message = message - self.percentage = percentage - } - - enum CodingKeys: CodingKey { - case kind - case cancellable - case message - case percentage - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "report" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of WorkDoneProgressReport is not 'report'" - ) - } - - self.cancellable = try container.decodeIfPresent(Bool.self, forKey: .cancellable) - self.message = try container.decodeIfPresent(String.self, forKey: .message) - self.percentage = try container.decodeIfPresent(Int.self, forKey: .percentage) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("report", forKey: .kind) - try container.encodeIfPresent(self.cancellable, forKey: .cancellable) - try container.encodeIfPresent(self.message, forKey: .message) - try container.encodeIfPresent(self.percentage, forKey: .percentage) - } -} - -public struct WorkDoneProgressEnd: Codable, Hashable, Sendable { - /// Optional, a final message indicating to for example indicate the outcome - /// of the operation. - public var message: String? - - public init(message: String? = nil) { - self.message = message - } - - enum CodingKeys: CodingKey { - case kind - case message - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "end" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of WorkDoneProgressReport is not 'end'" - ) - } - - self.message = try container.decodeIfPresent(String.self, forKey: .message) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("end", forKey: .kind) - try container.encodeIfPresent(self.message, forKey: .message) - } -} diff --git a/Sources/LanguageServerProtocol/PositionRange.swift b/Sources/LanguageServerProtocol/PositionRange.swift deleted file mode 100644 index 8f9c50186..000000000 --- a/Sources/LanguageServerProtocol/PositionRange.swift +++ /dev/null @@ -1,94 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -extension Range where Bound == Position { - - /// Create a range for a single position. - public init(_ pos: Position) { - self = pos..`, for use with `CustomCodable`. -public struct PositionRange: CustomCodableWrapper { - public var wrappedValue: Range - - public init(wrappedValue: Range) { - self.wrappedValue = wrappedValue - } - - fileprivate enum CodingKeys: String, CodingKey { - case lowerBound = "start" - case upperBound = "end" - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let lhs = try container.decode(Position.self, forKey: .lowerBound) - let rhs = try container.decode(Position.self, forKey: .upperBound) - self.wrappedValue = lhs..>`, for use with `CustomCodable`. -public struct PositionRangeArray: CustomCodableWrapper { - public var wrappedValue: [Range] - - public init(wrappedValue: [Range]) { - self.wrappedValue = wrappedValue - } - - public init(from decoder: Decoder) throws { - var values: [Range] = [] - var arrayContainer = try decoder.unkeyedContainer() - values.reserveCapacity(arrayContainer.count ?? 1) - - while !arrayContainer.isAtEnd { - let range = try arrayContainer.decode(PositionRange.self) - values.append(range.wrappedValue) - } - self.wrappedValue = values - } - - public func encode(to encoder: Encoder) throws { - var arrayContainer = encoder.unkeyedContainer() - for rangeValue in wrappedValue { - try arrayContainer.encode(PositionRange(wrappedValue: rangeValue)) - } - } -} - -extension Range: LSPAnyCodable where Bound == Position { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard case .dictionary(let start)? = dictionary[PositionRange.CodingKeys.lowerBound.stringValue], - let startPosition = Position(fromLSPDictionary: start), - case .dictionary(let end)? = dictionary[PositionRange.CodingKeys.upperBound.stringValue], - let endPosition = Position(fromLSPDictionary: end) - else { - return nil - } - self = startPosition.. LSPAny { - return .dictionary([ - PositionRange.CodingKeys.lowerBound.stringValue: lowerBound.encodeToLSPAny(), - PositionRange.CodingKeys.upperBound.stringValue: upperBound.encodeToLSPAny(), - ]) - } -} diff --git a/Sources/LanguageServerProtocol/RequestID.swift b/Sources/LanguageServerProtocol/RequestID.swift deleted file mode 100644 index ddf45cdbe..000000000 --- a/Sources/LanguageServerProtocol/RequestID.swift +++ /dev/null @@ -1,48 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum RequestID: Hashable, Sendable { - case string(String) - case number(Int) -} - -extension RequestID: Codable { - public init(from decoder: Decoder) throws { - let value = try decoder.singleValueContainer() - if let intValue = try? value.decode(Int.self) { - self = .number(intValue) - } else if let strValue = try? value.decode(String.self) { - self = .string(strValue) - } else { - throw MessageDecodingError.invalidRequest("could not decode request id") - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .string(let value): - try container.encode(value) - case .number(let value): - try container.encode(value) - } - } -} - -extension RequestID: CustomStringConvertible { - public var description: String { - switch self { - case .number(let n): return String(n) - case .string(let s): return "\"\(s)\"" - } - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ApplyEditRequest.swift b/Sources/LanguageServerProtocol/Requests/ApplyEditRequest.swift deleted file mode 100644 index f39c22b8e..000000000 --- a/Sources/LanguageServerProtocol/Requests/ApplyEditRequest.swift +++ /dev/null @@ -1,47 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the server to the client to modify resources on the client side. -/// -/// - Parameters: -/// - label: An optional label of the workspace edit. -/// - edit: The edits to apply. -public struct ApplyEditRequest: RequestType { - public static let method: String = "workspace/applyEdit" - public typealias Response = ApplyEditResponse - - /// An optional label of the workspace edit. - /// Used by the client's user interface for things such as - /// the stack to undo the workspace edit. - public var label: String? - - /// The edits to apply. - public var edit: WorkspaceEdit - - public init(label: String? = nil, edit: WorkspaceEdit) { - self.label = label - self.edit = edit - } -} - -public struct ApplyEditResponse: Codable, Hashable, ResponseType { - /// Indicates whether the edit was applied or not. - public var applied: Bool - - /// An optional textual description for why the edit was not applied. - public var failureReason: String? - - public init(applied: Bool, failureReason: String?) { - self.applied = applied - self.failureReason = failureReason - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CallHierarchyIncomingCallsRequest.swift b/Sources/LanguageServerProtocol/Requests/CallHierarchyIncomingCallsRequest.swift deleted file mode 100644 index 0c2946342..000000000 --- a/Sources/LanguageServerProtocol/Requests/CallHierarchyIncomingCallsRequest.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The request is sent from the client to the server to resolve the callers for -/// a given call hierarchy item. It is only issued if a server registers for the -/// `textDocument/prepareCallHierarchy` request. -public struct CallHierarchyIncomingCallsRequest: RequestType { - public static let method: String = "callHierarchy/incomingCalls" - public typealias Response = [CallHierarchyIncomingCall]? - - public var item: CallHierarchyItem - - public init(item: CallHierarchyItem) { - self.item = item - } -} - -/// Represents a caller (an incoming call) - an item that makes a call of the original `item`. -public struct CallHierarchyIncomingCall: ResponseType, Hashable { - /// The item that makes the call. - public var from: CallHierarchyItem - - /// The range(s) of calls inside the caller (the item denoted by `from`). - @CustomCodable - public var fromRanges: [Range] - - public init(from: CallHierarchyItem, fromRanges: [Range]) { - self.from = from - self.fromRanges = fromRanges - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CallHierarchyOutgoingCallsRequest.swift b/Sources/LanguageServerProtocol/Requests/CallHierarchyOutgoingCallsRequest.swift deleted file mode 100644 index 744be46b3..000000000 --- a/Sources/LanguageServerProtocol/Requests/CallHierarchyOutgoingCallsRequest.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The request is sent from the client to the server to resolve callees for a given call hierarchy item. -/// It is only issued if a server registers for the `textDocument/prepareCallHierarchy` request. -public struct CallHierarchyOutgoingCallsRequest: RequestType { - public static let method: String = "callHierarchy/outgoingCalls" - public typealias Response = [CallHierarchyOutgoingCall]? - - public var item: CallHierarchyItem - - public init(item: CallHierarchyItem) { - self.item = item - } -} - -/// Represents a callee (an outgoing call) - an item that is called by the original `item`. -public struct CallHierarchyOutgoingCall: ResponseType, Hashable { - /// The item that is called. - public var to: CallHierarchyItem - - /// The range(s) at which this item is called by the caller (the item inside - /// the `callHierarchy/outgoingCalls` request). - @CustomCodable - public var fromRanges: [Range] - - public init(to: CallHierarchyItem, fromRanges: [Range]) { - self.to = to - self.fromRanges = fromRanges - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CallHierarchyPrepareRequest.swift b/Sources/LanguageServerProtocol/Requests/CallHierarchyPrepareRequest.swift deleted file mode 100644 index 5f08772eb..000000000 --- a/Sources/LanguageServerProtocol/Requests/CallHierarchyPrepareRequest.swift +++ /dev/null @@ -1,35 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The call hierarchy request is sent from the client to the server to return a call hierarchy for the -/// language element of the given text document positions. -/// -/// The call hierarchy requests are executed in two steps: -/// 1. A call hierarchy item is resolved for the given text document position -/// (via `textDocument/prepareCallHierarchy`) -/// 2. The incoming or outgoing call hierarchy items are resolved for a call hierarchy item -/// (via `callHierarchy/incomingCalls` or `callHierarchy/outgoingCalls`) -public struct CallHierarchyPrepareRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/prepareCallHierarchy" - public typealias Response = [CallHierarchyItem]? - - /// The document in which to prepare the call hierarchy items. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to prepare the call hierarchy items. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CodeActionRequest.swift b/Sources/LanguageServerProtocol/Requests/CodeActionRequest.swift deleted file mode 100644 index 09db58055..000000000 --- a/Sources/LanguageServerProtocol/Requests/CodeActionRequest.swift +++ /dev/null @@ -1,165 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public typealias CodeActionProvider = @Sendable (CodeActionRequest) async throws -> [CodeAction] - -/// Request for returning all possible code actions for a given text document and range. -/// -/// The code action request is sent from the client to the server to compute commands for a given text -/// document and range. These commands are typically code fixes to either fix problems or to beautify/ -/// refactor code. -/// -/// Servers that provide code actions should set the `codeActions` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which the command was invoked. -/// - range: The specific range inside the document to search for code actions. -/// - context: The context of the request. -/// -/// - Returns: A list of code actions for the given range and context. -public struct CodeActionRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/codeAction" - public typealias Response = CodeActionRequestResponse? - - /// The document in which the command was invoked. - public var textDocument: TextDocumentIdentifier - - /// The range for which the command was invoked. - @CustomCodable - public var range: Range - - /// Context carrying additional information. - public var context: CodeActionContext - - public init(range: Range, context: CodeActionContext, textDocument: TextDocumentIdentifier) { - self._range = CustomCodable(wrappedValue: range) - self.context = context - self.textDocument = textDocument - } -} - -/// Wrapper type for the response of a CodeAction request. -/// If the client supports CodeAction literals, the encoded type will be the CodeAction array itself. -/// Otherwise, the encoded value will be an array of CodeActions' inner Command structs. -public enum CodeActionRequestResponse: ResponseType, Codable, Equatable { - case codeActions([CodeAction]) - case commands([Command]) - - public init(codeActions: [CodeAction], clientCapabilities: TextDocumentClientCapabilities.CodeAction?) { - if clientCapabilities?.codeActionLiteralSupport != nil { - // The client guarantees that unsupported kinds will be handled, and in - // practice some clients use `"codeActionKind":{"valueSet":[]}`, since - // they support all kinds anyway. - self = .codeActions(codeActions) - } else { - self = .commands(codeActions.compactMap { $0.command }) - } - } - - public init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if let codeActions = try? container.decode([CodeAction].self) { - self = .codeActions(codeActions) - } else if let commands = try? container.decode([Command].self) { - self = .commands(commands) - } else { - let error = "CodeActionRequestResponse has neither a CodeAction or a Command." - throw DecodingError.dataCorruptedError(in: container, debugDescription: error) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .codeActions(let codeActions): - try container.encode(codeActions) - case .commands(let commands): - try container.encode(commands) - } - } -} - -/// The reason why code actions were requested. -public struct CodeActionTriggerKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Code actions were explicitly requested by the user or by an extension. - public static let invoked = CodeActionTriggerKind(rawValue: 1) - - /// Code actions were requested automatically. - /// - /// This typically happens when current selection in a file changes, but can - /// also be triggered when file content changes. - public static let automatic = CodeActionTriggerKind(rawValue: 2) -} - -public struct CodeActionContext: Codable, Hashable, Sendable { - - /// An array of diagnostics. - public var diagnostics: [Diagnostic] - - /// Requested kind of actions to return. - /// If provided, actions of these kinds are filtered out by the client before being shown, - /// so servers can omit computing them. - public var only: [CodeActionKind]? - - /// The reason why code actions were requested. - public var triggerKind: CodeActionTriggerKind? - - public init( - diagnostics: [Diagnostic] = [], - only: [CodeActionKind]? = nil, - triggerKind: CodeActionTriggerKind? = nil - ) { - self.diagnostics = diagnostics - self.only = only - self.triggerKind = triggerKind - } -} - -public struct CodeAction: ResponseType, Hashable { - - /// A short, human-readable, title for this code action. - public var title: String - - /// The kind of the code action. - public var kind: CodeActionKind? - - /// The diagnostics that this code action resolves, if applicable. - public var diagnostics: [Diagnostic]? - - /// The workspace edit this code action performs. - public var edit: WorkspaceEdit? - - /// A command this code action executes. - /// If a code action provides an edit and a command, - /// first the edit is executed and then the command. - public var command: Command? - - public init( - title: String, - kind: CodeActionKind? = nil, - diagnostics: [Diagnostic]? = nil, - edit: WorkspaceEdit? = nil, - command: Command? = nil - ) { - self.title = title - self.kind = kind - self.diagnostics = diagnostics - self.edit = edit - self.command = command - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CodeActionResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/CodeActionResolveRequest.swift deleted file mode 100644 index a4197b843..000000000 --- a/Sources/LanguageServerProtocol/Requests/CodeActionResolveRequest.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct CodeActionResolveRequest: RequestType { - public static let method: String = "codeAction/resolve" - public typealias Response = CodeAction - - public var codeAction: CodeAction - - public init(codeAction: CodeAction) { - self.codeAction = codeAction - } - - public init(from decoder: Decoder) throws { - self.codeAction = try CodeAction(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try self.codeAction.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CodeLensRefreshRequest.swift b/Sources/LanguageServerProtocol/Requests/CodeLensRefreshRequest.swift deleted file mode 100644 index 41f65a133..000000000 --- a/Sources/LanguageServerProtocol/Requests/CodeLensRefreshRequest.swift +++ /dev/null @@ -1,19 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct CodeLensRefreshRequest: RequestType { - public static let method: String = "workspace/codeLens/refresh" - - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/CodeLensRequest.swift b/Sources/LanguageServerProtocol/Requests/CodeLensRequest.swift deleted file mode 100644 index b438cdd3b..000000000 --- a/Sources/LanguageServerProtocol/Requests/CodeLensRequest.swift +++ /dev/null @@ -1,50 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The code lens request is sent from the client to the server to compute code lenses for a given text document. -public struct CodeLensRequest: TextDocumentRequest { - public static let method: String = "textDocument/codeLens" - public typealias Response = [CodeLens]? - - /// The document to request code lens for. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -/// A code lens represents a command that should be shown along with -/// source text, like the number of references, a way to run tests, etc. -/// -/// A code lens is _unresolved_ when no command is associated to it. For -/// performance reasons the creation of a code lens and resolving should be done -/// in two stages. -public struct CodeLens: ResponseType, Hashable { - /// The range in which this code lens is valid. Should only span a single - /// line. - @CustomCodable - public var range: Range - - /// The command this code lens represents. - public var command: Command? - - /// A data entry field that is preserved on a code lens item between - /// a code lens and a code lens resolve request. - public var data: LSPAny? - - public init(range: Range, command: Command? = nil, data: LSPAny? = nil) { - self.range = range - self.command = command - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CodeLensResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/CodeLensResolveRequest.swift deleted file mode 100644 index b33db9e51..000000000 --- a/Sources/LanguageServerProtocol/Requests/CodeLensResolveRequest.swift +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The code lens resolve request is sent from the client to the server to resolve the command for a given code lens item. -public struct CodeLensResolveRequest: RequestType { - public static let method: String = "codeLens/resolve" - public typealias Response = CodeLens - - public var codeLens: CodeLens - - public init(codeLens: CodeLens) { - self.codeLens = codeLens - } - - public init(from decoder: Decoder) throws { - self.codeLens = try CodeLens(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try codeLens.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ColorPresentationRequest.swift b/Sources/LanguageServerProtocol/Requests/ColorPresentationRequest.swift deleted file mode 100644 index ff993b5e7..000000000 --- a/Sources/LanguageServerProtocol/Requests/ColorPresentationRequest.swift +++ /dev/null @@ -1,65 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The color presentation request is sent from the client to the server to obtain -/// a list of presentations for a color value at a given location. Clients can -/// use the result to modify a color reference, or show in a color picker -/// and let users pick one of the presentations -/// -/// - Parameters: -/// - textDocument: The document to request presentations for. -/// - color: The color information to request presentations for. -/// - range: The range where the color would be inserted. Serves as a context. -/// -/// - Returns: A list of color presentations for the given document. -public struct ColorPresentationRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/colorPresentation" - public typealias Response = [ColorPresentation] - - /// The document to request presentations for. - public var textDocument: TextDocumentIdentifier - - /// The color information to request presentations for. - public var color: Color - - /// The range where the color would be inserted. Serves as a context. - @CustomCodable - public var range: Range - - public init(textDocument: TextDocumentIdentifier, color: Color, range: Range) { - self.textDocument = textDocument - self.color = color - self._range = CustomCodable(wrappedValue: range) - } -} - -public struct ColorPresentation: ResponseType, Hashable { - /// The label of this color presentation. It will be shown on the color - /// picker header. By default this is also the text that is inserted when - /// selecting this color presentation. - public var label: String - - /// An edit which is applied to a document when selecting this - /// presentation for the color. When `falsy` the label is used. - public var textEdit: TextEdit? - - /// An optional array of additional text edits that are applied when - /// selecting this color presentation. Edits must not overlap with - /// the main edit nor with themselves. - public var additionalTextEdits: [TextEdit]? - - public init(label: String, textEdit: TextEdit?, additionalTextEdits: [TextEdit]?) { - self.label = label - self.textEdit = textEdit - self.additionalTextEdits = additionalTextEdits - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CompletionItemResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/CompletionItemResolveRequest.swift deleted file mode 100644 index 8c3a317bf..000000000 --- a/Sources/LanguageServerProtocol/Requests/CompletionItemResolveRequest.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct CompletionItemResolveRequest: RequestType { - public static let method: String = "completionItem/resolve" - public typealias Response = CompletionItem - - public var item: CompletionItem - - public init(item: CompletionItem) { - self.item = item - } - - public init(from decoder: Decoder) throws { - self.item = try CompletionItem(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try self.item.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CompletionRequest.swift b/Sources/LanguageServerProtocol/Requests/CompletionRequest.swift deleted file mode 100644 index 3d995a728..000000000 --- a/Sources/LanguageServerProtocol/Requests/CompletionRequest.swift +++ /dev/null @@ -1,204 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for code-completion items at the given document location. -/// -/// The server may - or may not - filter and sort the results before returning them. If the server -/// performs server-side filtering, it should set the `isIncomplete` flag on the result. However, -/// since there are no particular rules specified for server-side filtering, the client likely will -/// want to perform its own filtering as well. -/// -/// Servers that provide document highlights should set the `completionProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document to perform completion in. -/// - position: The location to perform completion at. -/// - context: Optional code-completion context. -/// -/// - Returns: A list of completion items to complete the code at the given position. -public struct CompletionRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/completion" - public typealias Response = CompletionList - - public var textDocument: TextDocumentIdentifier - - public var position: Position - - public var context: CompletionContext? - - public init( - textDocument: TextDocumentIdentifier, - position: Position, - context: CompletionContext? = nil - ) { - self.textDocument = textDocument - self.position = position - self.context = context - } -} - -/// How a completion was triggered -public struct CompletionTriggerKind: RawRepresentable, Codable, Hashable, Sendable { - /// Completion was triggered by typing an identifier (24x7 code complete), manual invocation (e.g Ctrl+Space) or via API. - public static let invoked = CompletionTriggerKind(rawValue: 1) - - /// Completion was triggered by a trigger character specified by the `triggerCharacters` properties of the `CompletionRegistrationOptions`. - public static let triggerCharacter = CompletionTriggerKind(rawValue: 2) - - /// Completion was re-triggered as the current completion list is incomplete. - public static let triggerFromIncompleteCompletions = CompletionTriggerKind(rawValue: 3) - - public let rawValue: Int - public init(rawValue: Int) { - self.rawValue = rawValue - } -} - -/// Contains additional information about the context in which a completion request is triggered. -public struct CompletionContext: Codable, Hashable, Sendable { - /// How the completion was triggered. - public var triggerKind: CompletionTriggerKind - - /// The trigger character (a single character) that has trigger code complete. Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` - public var triggerCharacter: String? - - public init(triggerKind: CompletionTriggerKind, triggerCharacter: String? = nil) { - self.triggerKind = triggerKind - self.triggerCharacter = triggerCharacter - } -} - -/// List of completion items. If this list has been filtered already, the `isIncomplete` flag -/// indicates that the client should re-query code-completions if the filter text changes. -public struct CompletionList: ResponseType, Hashable { - public struct InsertReplaceRanges: Codable, Hashable, Sendable { - @CustomCodable - var insert: Range - - @CustomCodable - var replace: Range - - public init(insert: Range, replace: Range) { - self.insert = insert - self.replace = replace - } - } - - public enum ItemDefaultsEditRange: Codable, Hashable, Sendable { - case range(Range) - case insertReplaceRanges(InsertReplaceRanges) - - public init(from decoder: Decoder) throws { - if let range = try? PositionRange(from: decoder).wrappedValue { - self = .range(range) - } else if let insertReplaceRange = try? InsertReplaceRanges(from: decoder) { - self = .insertReplaceRanges(insertReplaceRange) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected Range or InsertReplaceRanges" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .range(let range): - try PositionRange(wrappedValue: range).encode(to: encoder) - case .insertReplaceRanges(let insertReplaceRanges): - try insertReplaceRanges.encode(to: encoder) - } - } - } - - public struct ItemDefaults: Codable, Hashable, Sendable { - /// A default commit character set. - public var commitCharacters: [String]? - - /// A default edit range - public var editRange: ItemDefaultsEditRange? - - /// A default insert text format - public var insertTextFormat: InsertTextFormat? - - /// A default insert text mode - public var insertTextMode: InsertTextMode? - - /// A default data value. - public var data: LSPAny? - - public init( - commitCharacters: [String]? = nil, - editRange: ItemDefaultsEditRange? = nil, - insertTextFormat: InsertTextFormat? = nil, - insertTextMode: InsertTextMode? = nil, - data: LSPAny? = nil - ) { - self.commitCharacters = commitCharacters - self.editRange = editRange - self.insertTextFormat = insertTextFormat - self.insertTextMode = insertTextMode - self.data = data - } - } - - /// Whether the list of completions is "complete" or not. - /// - /// When this value is `true`, the client should re-query the server when doing further filtering. - public var isIncomplete: Bool - - /// In many cases the items of an actual completion result share the same - /// value for properties like `commitCharacters` or the range of a text - /// edit. A completion list can therefore define item defaults which will - /// be used if a completion item itself doesn't specify the value. - /// - /// If a completion list specifies a default value and a completion item - /// also specifies a corresponding value the one from the item is used. - /// - /// Servers are only allowed to return default values if the client - /// signals support for this via the `completionList.itemDefaults` - /// capability. - public var itemDefaults: ItemDefaults? - - /// The resulting completions. - public var items: [CompletionItem] - - public init(isIncomplete: Bool, itemDefaults: ItemDefaults? = nil, items: [CompletionItem]) { - self.isIncomplete = isIncomplete - self.itemDefaults = itemDefaults - self.items = items - } - - public init(from decoder: Decoder) throws { - // Try decoding as CompletionList - do { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.isIncomplete = try container.decode(Bool.self, forKey: .isIncomplete) - self.items = try container.decode([CompletionItem].self, forKey: .items) - return - } catch {} - - // Try decoding as [CompletionItem] - do { - self.items = try [CompletionItem](from: decoder) - self.isIncomplete = false - return - } catch {} - - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected CompletionList or [CompletionItem]" - ) - throw DecodingError.dataCorrupted(context) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/CreateWorkDoneProgressRequest.swift b/Sources/LanguageServerProtocol/Requests/CreateWorkDoneProgressRequest.swift deleted file mode 100644 index 397bb5290..000000000 --- a/Sources/LanguageServerProtocol/Requests/CreateWorkDoneProgressRequest.swift +++ /dev/null @@ -1,23 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct CreateWorkDoneProgressRequest: RequestType { - public static let method: String = "window/workDoneProgress/create" - public typealias Response = VoidResponse - - /// The token to be used to report progress. - public var token: ProgressToken - - public init(token: ProgressToken) { - self.token = token - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DeclarationRequest.swift b/Sources/LanguageServerProtocol/Requests/DeclarationRequest.swift deleted file mode 100644 index 37a3b7cce..000000000 --- a/Sources/LanguageServerProtocol/Requests/DeclarationRequest.swift +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to find the declarations(s) of the symbol at the given location. -/// -/// Looks up the symbol at the given position and returns a list of all -/// declarations involving that symbol in the workspace. -/// -/// This request differs from `DefinitionRequest` because a symbol usually has -/// only one definition but potentially has many declarations involving that -/// symbol. E.g. the definition of a type versus the forward declarations of that type. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: The location of the declaration(s). -public struct DeclarationRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/declaration" - public typealias Response = LocationsOrLocationLinksResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DefinitionRequest.swift b/Sources/LanguageServerProtocol/Requests/DefinitionRequest.swift deleted file mode 100644 index 4932aac40..000000000 --- a/Sources/LanguageServerProtocol/Requests/DefinitionRequest.swift +++ /dev/null @@ -1,39 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to find the definition(s) of the symbol at the given location. -/// -/// Looks up the symbol at the given position and returns a list of all definition of that symbol -/// across the whole workspace. -/// -/// Servers that provide document highlights should set the `definitionProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: The location of the definition(s). -public struct DefinitionRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/definition" - public typealias Response = LocationsOrLocationLinksResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DiagnosticsRefreshRequest.swift b/Sources/LanguageServerProtocol/Requests/DiagnosticsRefreshRequest.swift deleted file mode 100644 index 1ee6da3a9..000000000 --- a/Sources/LanguageServerProtocol/Requests/DiagnosticsRefreshRequest.swift +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DiagnosticsRefreshRequest: RequestType { - public static let method: String = "workspace/diagnostic/refresh" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/DoccDocumentationRequest.swift b/Sources/LanguageServerProtocol/Requests/DoccDocumentationRequest.swift deleted file mode 100644 index 58d447cf4..000000000 --- a/Sources/LanguageServerProtocol/Requests/DoccDocumentationRequest.swift +++ /dev/null @@ -1,68 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request that generates documentation for a symbol at a given cursor location **(LSP Extension)**. -/// -/// Primarily designed to support live preview of Swift documentation in editors. -/// -/// This request looks up the nearest documentable symbol (if any) at a given cursor location within -/// a text document and returns a `DoccDocumentationResponse`. The response contains a string -/// representing single JSON encoded DocC RenderNode. This RenderNode can then be rendered in an -/// editor via https://github.com/swiftlang/swift-docc-render. -/// -/// The position may be ommitted for documentation within DocC markdown and tutorial files as they -/// represent a single documentation page. It is only required for generating documentation within -/// Swift files as they usually contain multiple documentable symbols. -/// -/// Documentation can fail to be generated for a number of reasons. The most common of which being -/// that no documentable symbol could be found. In such cases the request will fail with a request -/// failed LSP error code (-32803) that contains a human-readable error message. This error message can -/// be displayed within the live preview editor to indicate that something has gone wrong. -/// -/// At the moment this request is only available on macOS and Linux. SourceKit-LSP will advertise -/// `textDocument/doccDocumentation` in its experimental server capabilities if it supports it. -/// -/// - Parameters: -/// - textDocument: The document to generate documentation for. -/// - position: The cursor position within the document. (optional) -/// -/// - Returns: A `DoccDocumentationResponse` for the given location, which may contain an error -/// message if documentation could not be converted. This error message can be displayed to the user -/// in the live preview editor. -/// -/// ### LSP Extension -/// -/// This request is an extension to LSP supported by SourceKit-LSP. -/// The client is expected to display the documentation in an editor using swift-docc-render. -public struct DoccDocumentationRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/doccDocumentation" - public typealias Response = DoccDocumentationResponse - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position? - - public init(textDocument: TextDocumentIdentifier, position: Position? = nil) { - self.textDocument = textDocument - self.position = position - } -} - -public struct DoccDocumentationResponse: ResponseType, Equatable { - public var renderNode: String - - public init(renderNode: String) { - self.renderNode = renderNode - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentColorRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentColorRequest.swift deleted file mode 100644 index a9f30cfef..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentColorRequest.swift +++ /dev/null @@ -1,65 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The document color request is sent from the client to the server to list -/// all color references found in a given text document. Along with the range, -/// a color value in RGB is returned. -/// Clients can use the result to decorate color references in an editor. -/// -/// - Parameters: -/// - textDocument: The document to search for color references. -/// -/// - Returns: A list of color references for the given document. -public struct DocumentColorRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/documentColor" - public typealias Response = [ColorInformation] - - /// The document in which to search for color references. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -public struct ColorInformation: ResponseType, Hashable { - /// The range in the document where this color appears. - @CustomCodable - public var range: Range - - /// The actual color value for this color range. - public var color: Color - - public init(range: Range, color: Color) { - self._range = CustomCodable(wrappedValue: range) - self.color = color - } -} - -/// Represents a color in RGBA space. -public struct Color: Hashable, Codable, Sendable { - /// The red component of this color in the range [0-1]. - public var red: Double - /// The green component of this color in the range [0-1]. - public var green: Double - /// The blue component of this color in the range [0-1]. - public var blue: Double - /// The alpha component of this color in the range [0-1]. - public var alpha: Double - - public init(red: Double, green: Double, blue: Double, alpha: Double) { - self.red = red - self.green = green - self.blue = blue - self.alpha = alpha - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentDiagnosticsRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentDiagnosticsRequest.swift deleted file mode 100644 index 63ed427af..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentDiagnosticsRequest.swift +++ /dev/null @@ -1,192 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DocumentDiagnosticsRequest: TextDocumentRequest { - public static let method: String = "textDocument/diagnostic" - public typealias Response = DocumentDiagnosticReport - - /// The text document. - public var textDocument: TextDocumentIdentifier - - /// The additional identifier provided during registration. - public var identifier: String? - - /// The result id of a previous response if provided. - public var previousResultId: String? - - public init(textDocument: TextDocumentIdentifier, identifier: String? = nil, previousResultId: String? = nil) { - self.textDocument = textDocument - self.identifier = identifier - self.previousResultId = previousResultId - } -} - -/// The result of a document diagnostic pull request. A report can -/// either be a full report containing all diagnostics for the -/// requested document or a unchanged report indicating that nothing -/// has changed in terms of diagnostics in comparison to the last -/// pull request. -public enum DocumentDiagnosticReport: ResponseType, Codable, Hashable { - case full(RelatedFullDocumentDiagnosticReport) - case unchanged(RelatedUnchangedDocumentDiagnosticReport) - - public init(from decoder: Decoder) throws { - if let full = try? RelatedFullDocumentDiagnosticReport(from: decoder) { - self = .full(full) - } else if let unchanged = try? RelatedUnchangedDocumentDiagnosticReport(from: decoder) { - self = .unchanged(unchanged) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected RelatedFullDocumentDiagnosticReport or RelatedUnchangedDocumentDiagnosticReport" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .full(let full): - try full.encode(to: encoder) - case .unchanged(let unchanged): - try unchanged.encode(to: encoder) - } - } -} - -/// The document diagnostic report kinds. -public struct DocumentDiagnosticReportKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// A diagnostic report with a full - /// set of problems. - public static let full = DocumentDiagnosticReportKind(rawValue: "full") - - /// A report indicating that the last - /// returned report is still accurate. - public static let unchanged = DocumentDiagnosticReportKind(rawValue: "unchanged") -} - -/// A diagnostic report with a full set of problems. -public struct RelatedFullDocumentDiagnosticReport: Codable, Hashable, Sendable { - /// An optional result id. If provided it will - /// be sent on the next diagnostic request for the - /// same document. - public var resultId: String? - - /// The actual items. - public var items: [Diagnostic] - - /// Diagnostics of related documents. This information is useful - /// in programming languages where code in a file A can generate - /// diagnostics in a file B which A depends on. An example of - /// such a language is C/C++ where marco definitions in a file - /// a.cpp and result in errors in a header file b.hpp. - public var relatedDocuments: [DocumentURI: DocumentDiagnosticReport]? - - public init( - resultId: String? = nil, - items: [Diagnostic], - relatedDocuments: [DocumentURI: DocumentDiagnosticReport]? = nil - ) { - self.resultId = resultId - self.items = items - self.relatedDocuments = relatedDocuments - } - - enum CodingKeys: CodingKey { - case kind - case resultId - case items - case relatedDocuments - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(DocumentDiagnosticReportKind.self, forKey: .kind) - guard kind == .full else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of FullDocumentDiagnosticReport is not 'full'" - ) - } - self.resultId = try container.decodeIfPresent(String.self, forKey: .resultId) - self.items = try container.decode([Diagnostic].self, forKey: .items) - self.relatedDocuments = try container.decodeIfPresent( - [DocumentURI: DocumentDiagnosticReport].self, - forKey: .relatedDocuments - ) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(DocumentDiagnosticReportKind.full, forKey: .kind) - try container.encodeIfPresent(self.resultId, forKey: .resultId) - try container.encode(self.items, forKey: .items) - try container.encodeIfPresent(self.relatedDocuments, forKey: .relatedDocuments) - } -} - -/// A diagnostic report indicating that the last returned -/// report is still accurate. -public struct RelatedUnchangedDocumentDiagnosticReport: Codable, Hashable, Sendable { - /// A result id which will be sent on the next - /// diagnostic request for the same document. - public var resultId: String - - /// Diagnostics of related documents. This information is useful - /// in programming languages where code in a file A can generate - /// diagnostics in a file B which A depends on. An example of - /// such a language is C/C++ where marco definitions in a file - /// a.cpp and result in errors in a header file b.hpp. - public var relatedDocuments: [DocumentURI: DocumentDiagnosticReport]? - - public init(resultId: String, relatedDocuments: [DocumentURI: DocumentDiagnosticReport]? = nil) { - self.resultId = resultId - self.relatedDocuments = relatedDocuments - } - - enum CodingKeys: CodingKey { - case kind - case resultId - case relatedDocuments - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(DocumentDiagnosticReportKind.self, forKey: .kind) - guard kind == .unchanged else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of FullDocumentDiagnosticReport is not 'unchanged'" - ) - } - self.resultId = try container.decode(String.self, forKey: .resultId) - self.relatedDocuments = try container.decodeIfPresent( - [DocumentURI: DocumentDiagnosticReport].self, - forKey: .relatedDocuments - ) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(DocumentDiagnosticReportKind.unchanged, forKey: .kind) - try container.encode(self.resultId, forKey: .resultId) - try container.encodeIfPresent(self.relatedDocuments, forKey: .relatedDocuments) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentHighlightRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentHighlightRequest.swift deleted file mode 100644 index 05277b968..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentHighlightRequest.swift +++ /dev/null @@ -1,70 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to find document ranges that should be highlighted to match the given cursor position. -/// -/// This is typically used to highlight all references to the symbol under the cursor that are found -/// within a single document. Unlike the `references` request, this is scoped to one document and -/// has a DocumentHighlightKind that may include fuzzy (`.text`) matches. -/// -/// Servers that provide document highlights should set the`documentHighlightProvider` server -/// capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: An array of document highlight ranges, if any. -public struct DocumentHighlightRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/documentHighlight" - public typealias Response = [DocumentHighlight]? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -/// The kind of document highlight - read, write, or text (fuzzy). -public enum DocumentHighlightKind: Int, Codable, Hashable, Sendable { - - /// Textual match. - case text = 1 - - /// A read of the symbol. - case read = 2 - - /// A write to the symbol. - case write = 3 -} - -/// A document range to highlight. -public struct DocumentHighlight: ResponseType, Hashable { - - /// The range of the highlight. - @CustomCodable - public var range: Range - - /// What kind of reference this is. Default is `.text`. - public var kind: DocumentHighlightKind? - - public init(range: Range, kind: DocumentHighlightKind?) { - self._range = CustomCodable(wrappedValue: range) - self.kind = kind - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentLinkRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentLinkRequest.swift deleted file mode 100644 index f3fea88e1..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentLinkRequest.swift +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The document links request is sent from the client to the server to request the location of links in a document. -public struct DocumentLinkRequest: TextDocumentRequest { - public static let method: String = "textDocument/documentLink" - public typealias Response = [DocumentLink]? - - /// The document to provide document links for. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -/// A document link is a range in a text document that links to an internal or -/// external resource, like another text document or a web site. -public struct DocumentLink: ResponseType, Hashable { - /// The range this link applies to. - @CustomCodable - public var range: Range - - /// The uri this link points to. If missing a resolve request is sent later. - public var target: DocumentURI? - - /// The tooltip text when you hover over this link. - /// - /// If a tooltip is provided, is will be displayed in a string that includes - /// instructions on how to trigger the link, such as `{0} (ctrl + click)`. - /// The specific instructions vary depending on OS, user settings, and - /// localization. - public var tooltip: String? - - /// A data entry field that is preserved on a document link between a - /// DocumentLinkRequest and a DocumentLinkResolveRequest. - public var data: LSPAny? - - public init(range: Range, target: DocumentURI? = nil, tooltip: String? = nil, data: LSPAny? = nil) { - self.range = range - self.target = target - self.tooltip = tooltip - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentLinkResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentLinkResolveRequest.swift deleted file mode 100644 index fc88fb1d3..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentLinkResolveRequest.swift +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The document links request is sent from the client to the server to request the location of links in a document. -public struct DocumentLinkResolveRequest: RequestType { - public static let method: String = "documentLink/resolve" - public typealias Response = DocumentLink - - public var documentLink: DocumentLink - - public init(documentLink: DocumentLink) { - self.documentLink = documentLink - } - - public init(from decoder: Decoder) throws { - self.documentLink = try DocumentLink(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try self.documentLink.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensDeltaRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensDeltaRequest.swift deleted file mode 100644 index 55881c03b..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensDeltaRequest.swift +++ /dev/null @@ -1,87 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DocumentSemanticTokensDeltaRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/semanticTokens/full/delta" - public typealias Response = DocumentSemanticTokensDeltaResponse? - - /// The document to fetch semantic tokens for. - public var textDocument: TextDocumentIdentifier - - /// The result identifier of a previous response, which acts as the diff base for the delta. - /// This can either point to a full response or a delta response, depending on what was - /// last received by the client. - public var previousResultId: String - - public init(textDocument: TextDocumentIdentifier, previousResultId: String) { - self.textDocument = textDocument - self.previousResultId = previousResultId - } -} - -public enum DocumentSemanticTokensDeltaResponse: ResponseType, Codable, Equatable { - case tokens(DocumentSemanticTokensResponse) - case delta(SemanticTokensDelta) - - public init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if let tokens = try? container.decode(DocumentSemanticTokensResponse.self) { - self = .tokens(tokens) - } else if let delta = try? container.decode(SemanticTokensDelta.self) { - self = .delta(delta) - } else { - let error = "DocumentSemanticTokensDeltaResponse has neither SemanticTokens or SemanticTokensDelta." - throw DecodingError.dataCorruptedError(in: container, debugDescription: error) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .tokens(let tokens): - try container.encode(tokens) - case .delta(let delta): - try container.encode(delta) - } - } -} - -public struct SemanticTokensDelta: Codable, Hashable, Sendable { - /// An optional result identifier which enables supporting clients to request semantic token deltas - /// subsequent requests. - public var resultId: String? - - /// The edits to transform a previous result into a new result. - public var edits: [SemanticTokensEdit] - - public init(resultId: String? = nil, edits: [SemanticTokensEdit]) { - self.resultId = resultId - self.edits = edits - } -} - -public struct SemanticTokensEdit: Codable, Hashable, Sendable { - /// Start offset of the edit. - public var start: Int - - /// The number of elements to remove. - public var deleteCount: Int - - /// The elements to insert. - public var data: [UInt32]? - - public init(start: Int, deleteCount: Int, data: [UInt32]? = nil) { - self.start = start - self.deleteCount = deleteCount - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRangeRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRangeRequest.swift deleted file mode 100644 index 42fbcba8b..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRangeRequest.swift +++ /dev/null @@ -1,28 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DocumentSemanticTokensRangeRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/semanticTokens/range" - public typealias Response = DocumentSemanticTokensResponse? - - /// The document to fetch semantic tokens for. - public var textDocument: TextDocumentIdentifier - - /// The range to fetch semantic tokens for. - @CustomCodable - public var range: Range - - public init(textDocument: TextDocumentIdentifier, range: Range) { - self.textDocument = textDocument - self.range = range - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRequest.swift deleted file mode 100644 index 10019afeb..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentSemanticTokensRequest.swift +++ /dev/null @@ -1,37 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct DocumentSemanticTokensRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/semanticTokens/full" - public typealias Response = DocumentSemanticTokensResponse? - - /// The document to fetch semantic tokens for. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -public struct DocumentSemanticTokensResponse: ResponseType, Hashable { - /// An optional result identifier which enables supporting clients to request semantic token deltas - /// subsequent requests. - public var resultId: String? - - /// Raw tokens data. - public var data: [UInt32] - - public init(resultId: String? = nil, data: [UInt32]) { - self.resultId = resultId - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentSymbolRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentSymbolRequest.swift deleted file mode 100644 index 9ec14a5c9..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentSymbolRequest.swift +++ /dev/null @@ -1,121 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for symbols to display in the document outline. -/// -/// This is used to provide list of all symbols in the document and display inside which -/// type or function the cursor is currently in. -/// -/// Servers that provide document highlights should set the `documentSymbolProvider` server -/// capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// -/// - Returns: An array of document symbols, if any. -public struct DocumentSymbolRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/documentSymbol" - public typealias Response = DocumentSymbolResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -public enum DocumentSymbolResponse: ResponseType, Hashable { - case documentSymbols([DocumentSymbol]) - case symbolInformation([SymbolInformation]) - - public init(from decoder: Decoder) throws { - if let documentSymbols = try? [DocumentSymbol](from: decoder) { - self = .documentSymbols(documentSymbols) - } else if let symbolInformation = try? [SymbolInformation](from: decoder) { - self = .symbolInformation(symbolInformation) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected [DocumentSymbol] or [SymbolInformation]" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .documentSymbols(let documentSymbols): - try documentSymbols.encode(to: encoder) - case .symbolInformation(let symbolInformation): - try symbolInformation.encode(to: encoder) - } - } -} - -/// Represents programming constructs like variables, classes, interfaces etc. that appear -/// in a document. Document symbols can be hierarchical and they have two ranges: one that encloses -/// its definition and one that points to its most interesting range, e.g. the range of an identifier. -public struct DocumentSymbol: Hashable, Codable, Sendable { - - /// The name of this symbol. Will be displayed in the user interface and therefore must not be - /// an empty string or a string only consisting of white spaces. - public var name: String - - /// More detail for this symbol, e.g the signature of a function. - public var detail: String? - - /// The kind of this symbol. - public var kind: SymbolKind - - /// Tags for this document symbol. - public var tags: [SymbolTag]? - - /// Indicates if this symbol is deprecated. - public var deprecated: Bool? - - /// The range enclosing this symbol not including leading/trailing whitespace but everything else - /// like comments. This information is typically used to determine if the clients cursor is - /// inside the symbol to reveal in the symbol in the UI. - @CustomCodable - public var range: Range - - /// The range that should be selected and revealed when this symbol is being picked, - /// e.g the name of a function. - /// - /// Must be contained by the `range`. - @CustomCodable - public var selectionRange: Range - - /// Children of this symbol, e.g. properties of a class. - public var children: [DocumentSymbol]? - - public init( - name: String, - detail: String? = nil, - kind: SymbolKind, - tags: [SymbolTag]? = nil, - deprecated: Bool? = nil, - range: Range, - selectionRange: Range, - children: [DocumentSymbol]? = nil - ) { - self.name = name - self.detail = detail - self.kind = kind - self.tags = tags - self.deprecated = deprecated - self._range = CustomCodable(wrappedValue: range) - self._selectionRange = CustomCodable(wrappedValue: selectionRange) - self.children = children - } -} diff --git a/Sources/LanguageServerProtocol/Requests/DocumentTestsRequest.swift b/Sources/LanguageServerProtocol/Requests/DocumentTestsRequest.swift deleted file mode 100644 index c79dffac8..000000000 --- a/Sources/LanguageServerProtocol/Requests/DocumentTestsRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A request that returns symbols for all the test classes and test methods within a file. -/// -/// **(LSP Extension)** -public struct DocumentTestsRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/tests" - public typealias Response = [TestItem] - - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ExecuteCommandRequest.swift b/Sources/LanguageServerProtocol/Requests/ExecuteCommandRequest.swift deleted file mode 100644 index efbe44ea6..000000000 --- a/Sources/LanguageServerProtocol/Requests/ExecuteCommandRequest.swift +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request sent from the client to trigger command execution on the server. -/// -/// The execution of this request can be the result of a request that returns a command, -/// such as CodeActionsRequest and CodeLensRequest. In most cases, the server creates a WorkspaceEdit -/// structure and applies the changes to the workspace using the ApplyEditRequest. -/// -/// Servers that provide command execution should set the `executeCommand` server capability. -/// -/// - Parameters: -/// - command: The command to be executed. -/// - arguments: The arguments to use when executing the command. -public struct ExecuteCommandRequest: RequestType { - public static let method: String = "workspace/executeCommand" - public typealias Response = LSPAny? - - /// The command to be executed. - public var command: String - - /// Arguments that the command should be invoked with. - public var arguments: [LSPAny]? - - public init(command: String, arguments: [LSPAny]?) { - self.command = command - self.arguments = arguments - } -} diff --git a/Sources/LanguageServerProtocol/Requests/FoldingRangeRequest.swift b/Sources/LanguageServerProtocol/Requests/FoldingRangeRequest.swift deleted file mode 100644 index 63bac96c9..000000000 --- a/Sources/LanguageServerProtocol/Requests/FoldingRangeRequest.swift +++ /dev/null @@ -1,101 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for returning all folding ranges found in a given text document. -/// -/// Searches a document and returns a list of ranges of code that can be folded. -/// -/// Servers that provide folding ranges should set the `foldingRanges` server capability. -/// -/// - Parameters: -/// - textDocument: The document to search for folding ranges. -/// -/// - Returns: A list of folding ranges for the given document. -public struct FoldingRangeRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/foldingRange" - public typealias Response = [FoldingRange]? - - public var textDocument: TextDocumentIdentifier - - public init(textDocument: TextDocumentIdentifier) { - self.textDocument = textDocument - } -} - -/// A single folding range result. -public struct FoldingRange: ResponseType, Hashable { - - /// The zero-based line number from where the folded range starts. - public var startLine: Int - - /// The zero-based character offset from where the folded range starts. - /// If not defined, defaults to the length of the start line. - public var startUTF16Index: Int? - - /// The zero-based line number where the folded range ends. - public var endLine: Int - - /// The zero-based character offset before the folded range ends. - /// If not defined, defaults to the length of the end line. - public var endUTF16Index: Int? - - /// Describes the kind of the folding range such as `comment' or 'region'. The kind - /// is used to categorize folding ranges and used by commands like 'Fold all comments'. - public var kind: FoldingRangeKind? - - /// The text that the client should show when the specified range is - /// collapsed. If not defined or not supported by the client, a default - /// will be chosen by the client. - public var collapsedText: String? - - public init( - startLine: Int, - startUTF16Index: Int? = nil, - endLine: Int, - endUTF16Index: Int? = nil, - kind: FoldingRangeKind? = nil, - collapsedText: String? = nil - ) { - self.startLine = startLine - self.startUTF16Index = startUTF16Index - self.endLine = endLine - self.endUTF16Index = endUTF16Index - self.kind = kind - self.collapsedText = collapsedText - } -} - -extension FoldingRange: Codable { - private enum CodingKeys: String, CodingKey { - case startLine - case startUTF16Index = "startCharacter" - case endLine - case endUTF16Index = "endCharacter" - case kind - } -} - -extension FoldingRange: Comparable { - - public static func < (lhs: FoldingRange, rhs: FoldingRange) -> Bool { - return lhs.comparableKey < rhs.comparableKey - } - - private var comparableKey: (Int, Int, Int, Int, String) { - return ( - startLine, - startUTF16Index ?? Int.max, - endLine, endUTF16Index ?? Int.max, - kind?.rawValue ?? "" - ) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/FormattingRequests.swift b/Sources/LanguageServerProtocol/Requests/FormattingRequests.swift deleted file mode 100644 index 9d8bbdca9..000000000 --- a/Sources/LanguageServerProtocol/Requests/FormattingRequests.swift +++ /dev/null @@ -1,141 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to format an entire document. -/// -/// Servers that provide formatting should set the`documentFormattingProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document to format. -/// - options: Options to customize the formatting. -/// -/// - Returns: An array of of text edits describing the formatting changes to the document, if any. -public struct DocumentFormattingRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/formatting" - public typealias Response = [TextEdit]? - - /// The document to format. - public var textDocument: TextDocumentIdentifier - - /// Options to customize the formatting. - public var options: FormattingOptions - - public init(textDocument: TextDocumentIdentifier, options: FormattingOptions) { - self.textDocument = textDocument - self.options = options - } -} - -/// Request to format a specified range within a document. -/// -/// Servers that provide range formatting should set the`documentRangeFormattingProvider` server -/// capability. -/// -/// - Parameters: -/// - textDocument: he document in which to perform formatting. -/// - range: The range to format within `textDocument`. -/// - options: Options to customize the formatting. -/// -/// - Returns: An array of of text edits describing the formatting changes to the document, if any. -public struct DocumentRangeFormattingRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/rangeFormatting" - public typealias Response = [TextEdit]? - - /// The document in which to perform formatting. - public var textDocument: TextDocumentIdentifier - - /// The range to format within `textDocument`. - @CustomCodable - public var range: Range - - /// Options to customize the formatting. - public var options: FormattingOptions - - public init(textDocument: TextDocumentIdentifier, range: Range, options: FormattingOptions) { - self.textDocument = textDocument - self.range = range - self.options = options - } -} - -/// Request to format part of a document during typing. -/// -/// While `Document[Range]Formatting` requests are appropriate for performing bulk formatting of a -/// document, on-type formatting is meant for providing lightweight formatting during typing. It -/// is triggered in response to trigger characters being typed. -/// -/// Servers that provide range formatting should set the`documentOnTypeFormattingProvider` server -/// capability. -/// -/// - Parameters: -/// - textDocument: he document in which to perform formatting. -/// - position: The position at which the request was sent. -/// - ch: The character that triggered the formatting. -/// - options: Options to customize the formatting. -/// -/// - Returns: An array of of text edits describing the formatting changes to the document, if any. -public struct DocumentOnTypeFormattingRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/onTypeFormatting" - public typealias Response = [TextEdit]? - - /// The document in which to perform formatting. - public var textDocument: TextDocumentIdentifier - - /// The position at which the request was sent, which is immediately after the trigger character. - public var position: Position - - /// The character that triggered the formatting. - public var ch: String - - /// Options to customize the formatting. - public var options: FormattingOptions - - public init(textDocument: TextDocumentIdentifier, position: Position, ch: String, options: FormattingOptions) { - self.textDocument = textDocument - self.position = position - self.ch = ch - self.options = options - } -} - -/// Options to customize how document formatting requests are performed. -public struct FormattingOptions: Codable, Hashable, Sendable { - - /// The number of space characters in a tab. - public var tabSize: Int - - /// Whether to use spaces instead of tabs. - public var insertSpaces: Bool - - /// Trim trailing whitespace on a line. - public var trimTrailingWhitespace: Bool? - - /// Insert a newline character at the end of the file if one does not exist. - public var insertFinalNewline: Bool? - - /// Trim all newlines after the final newline at the end of the file. - public var trimFinalNewlines: Bool? - - public init( - tabSize: Int, - insertSpaces: Bool, - trimTrailingWhitespace: Bool? = nil, - insertFinalNewline: Bool? = nil, - trimFinalNewlines: Bool? = nil - ) { - self.tabSize = tabSize - self.insertSpaces = insertSpaces - self.trimTrailingWhitespace = trimTrailingWhitespace - self.insertFinalNewline = insertFinalNewline - self.trimFinalNewlines = trimFinalNewlines - } -} diff --git a/Sources/LanguageServerProtocol/Requests/GetReferenceDocumentRequest.swift b/Sources/LanguageServerProtocol/Requests/GetReferenceDocumentRequest.swift deleted file mode 100644 index eb3a233f1..000000000 --- a/Sources/LanguageServerProtocol/Requests/GetReferenceDocumentRequest.swift +++ /dev/null @@ -1,44 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the client to the server asking for contents of a URI having a custom scheme **(LSP Extension)** -/// For example: "sourcekit-lsp:" -/// -/// - Parameters: -/// - uri: The `DocumentUri` of the custom scheme url for which content is required -/// -/// - Returns: `GetReferenceDocumentResponse` which contains the `content` to be displayed. -/// -/// ### LSP Extension -/// -/// This request is an extension to LSP supported by SourceKit-LSP. -/// Enable the experimental client capability `"workspace/getReferenceDocument"` so that the server responds with -/// reference document URLs for certain requests or commands whenever possible. -public struct GetReferenceDocumentRequest: RequestType { - public static let method: String = "workspace/getReferenceDocument" - public typealias Response = GetReferenceDocumentResponse - - public var uri: DocumentURI - - public init(uri: DocumentURI) { - self.uri = uri - } -} - -/// Response containing `content` of `GetReferenceDocumentRequest` -public struct GetReferenceDocumentResponse: ResponseType { - public var content: String - - public init(content: String) { - self.content = content - } -} diff --git a/Sources/LanguageServerProtocol/Requests/HoverRequest.swift b/Sources/LanguageServerProtocol/Requests/HoverRequest.swift deleted file mode 100644 index 87c1d407c..000000000 --- a/Sources/LanguageServerProtocol/Requests/HoverRequest.swift +++ /dev/null @@ -1,123 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for documentation information about the symbol at a given location. -/// -/// This request looks up the symbol (if any) at a given text document location and returns the -/// documentation markup content for that location, suitable to show in an dialog when hovering over -/// that symbol in an editor. -/// -/// Servers that provide document highlights should set the `hoverProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: HoverResponse for the given location, which contains the `MarkupContent`. -public struct HoverRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/hover" - public typealias Response = HoverResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -/// Documentation markup contents for a symbol found by the hover request. -public struct HoverResponse: ResponseType, Hashable { - - /// The documentation markup content. - public var contents: HoverResponseContents - - /// An optional range to visually distinguish during hover. - @CustomCodable - public var range: Range? - - public init(contents: HoverResponseContents, range: Range?) { - self.contents = contents - self._range = CustomCodable(wrappedValue: range) - } -} - -public enum HoverResponseContents: Hashable, Sendable { - case markedStrings([MarkedString]) - case markupContent(MarkupContent) -} - -public enum MarkedString: Hashable { - private struct MarkdownCodeBlock: Codable { - let language: String - let value: String - } - - case markdown(value: String) - case codeBlock(language: String, value: String) -} - -extension MarkedString: Codable, Sendable { - public init(from decoder: Decoder) throws { - if let value = try? decoder.singleValueContainer().decode(String.self) { - self = .markdown(value: value) - } else if let codeBlock = try? MarkdownCodeBlock(from: decoder) { - self = .codeBlock(language: codeBlock.language, value: codeBlock.value) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected String or MarkdownCodeBlock" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .markdown(let value): - try value.encode(to: encoder) - case .codeBlock(let language, let value): - try MarkdownCodeBlock(language: language, value: value).encode(to: encoder) - } - } -} - -extension HoverResponseContents: Codable { - public init(from decoder: Decoder) throws { - if let value = try? MarkupContent(from: decoder) { - self = .markupContent(value) - } else if let value = try? [MarkedString](from: decoder) { - self = .markedStrings(value) - } else if let value = try? MarkedString(from: decoder) { - self = .markedStrings([value]) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected MarkedString, [MarkedString], or MarkupContent" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .markedStrings(let value): - try value.encode(to: encoder) - case .markupContent(let value): - try value.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ImplementationRequest.swift b/Sources/LanguageServerProtocol/Requests/ImplementationRequest.swift deleted file mode 100644 index 347e6a966..000000000 --- a/Sources/LanguageServerProtocol/Requests/ImplementationRequest.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The go to implementation request is sent from the client to the server -/// to resolve the implementation location of a symbol at a given -/// text document position. -/// -/// Servers that provide Goto Implementation support should set -/// the `implementationProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which the given symbol is located. -/// - position: The document location of a given symbol. -/// -/// - Returns: The location of the implementations of protocol requirements, -/// protocol conforming types, subclasses, or overrides. -public struct ImplementationRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/implementation" - public typealias Response = LocationsOrLocationLinksResponse? - - /// The document in which the given symbol is located. - public var textDocument: TextDocumentIdentifier - - /// The document location of a given symbol. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/IndexedRenameRequest.swift b/Sources/LanguageServerProtocol/Requests/IndexedRenameRequest.swift deleted file mode 100644 index c443f2b66..000000000 --- a/Sources/LanguageServerProtocol/Requests/IndexedRenameRequest.swift +++ /dev/null @@ -1,104 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Rename all occurrences of a symbol named `oldName` to `newName` at the -/// given `positions`. -/// -/// The use case of this method is for when the positions to rename are already -/// known, eg. from an index lookup outside of clangd's built-in index. In -/// particular, it determines the edits necessary to rename multi-piece -/// Objective-C selector names. -/// -/// `textDocument` is used to determine the language options for the symbol to -/// rename, eg. to decide whether `oldName` and `newName` are Objective-C -/// selectors or normal identifiers. -/// -/// This is a clangd extension. -public struct IndexedRenameRequest: TextDocumentRequest, Hashable { - public static let method: String = "workspace/indexedRename" - public typealias Response = WorkspaceEdit? - - /// The document in which the declaration to rename is declared. Its compiler - /// arguments are used to infer language settings for the rename. - public var textDocument: TextDocumentIdentifier - - /// The old name of the symbol. - public var oldName: String - - /// The new name of the symbol. - public var newName: String - - /// The positions at which the symbol is known to appear and that should be - /// renamed. The key is a document URI - public var positions: [DocumentURI: [Position]] - - public init( - textDocument: TextDocumentIdentifier, - oldName: String, - newName: String, - positions: [DocumentURI: [Position]] - ) { - self.textDocument = textDocument - self.oldName = oldName - self.newName = newName - self.positions = positions - } -} - -// Workaround for Codable not correctly encoding dictionaries whose keys aren't strings. -extension IndexedRenameRequest: Codable { - private enum CodingKeys: CodingKey { - case textDocument - case oldName - case newName - case positions - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - - self.textDocument = try container.decode( - TextDocumentIdentifier.self, - forKey: IndexedRenameRequest.CodingKeys.textDocument - ) - self.oldName = try container.decode(String.self, forKey: IndexedRenameRequest.CodingKeys.oldName) - self.newName = try container.decode(String.self, forKey: IndexedRenameRequest.CodingKeys.newName) - self.positions = try container.decode([String: [Position]].self, forKey: .positions).compactMapKeys { - try? DocumentURI(string: $0) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - try container.encode(self.textDocument, forKey: IndexedRenameRequest.CodingKeys.textDocument) - try container.encode(self.oldName, forKey: IndexedRenameRequest.CodingKeys.oldName) - try container.encode(self.newName, forKey: IndexedRenameRequest.CodingKeys.newName) - try container.encode( - self.positions.compactMapKeys { $0.stringValue }, - forKey: IndexedRenameRequest.CodingKeys.positions - ) - - } -} - -fileprivate extension Dictionary { - func compactMapKeys(_ transform: (Key) -> NewKeyType?) -> [NewKeyType: Value] { - let newKeysAndValues = self.compactMap { (key, value) -> (NewKeyType, Value)? in - guard let newKey = transform(key) else { - return nil - } - return (newKey, value) - } - return [NewKeyType: Value](uniqueKeysWithValues: newKeysAndValues) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/InitializeRequest.swift b/Sources/LanguageServerProtocol/Requests/InitializeRequest.swift deleted file mode 100644 index 226cf2e21..000000000 --- a/Sources/LanguageServerProtocol/Requests/InitializeRequest.swift +++ /dev/null @@ -1,133 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to initialize the language server. -/// -/// This is the first request sent by the client, providing the server with the client's -/// capabilities, configuration options, and initial information about the current workspace. The -/// server replies with its own capabilities, which allows the two sides to agree about the set of -/// supported protocol methods and values. -/// -/// - Parameters: -/// - processId: The process identifier (pid) of the client process. -/// - rootURI: The workspace URI, or nil if no workspace is open. -/// - initializationOptions: User-provided options. -/// - capabilities: The capabilities provided by the client editor. -/// - trace: Whether to enable tracing. -/// - workspaceFolders: The workspace folders configured, if the client supports multiple workspace -/// folders. -/// -/// - Returns: -public struct InitializeRequest: RequestType, Hashable { - /// Information about the client - public struct ClientInfo: Codable, Hashable, Sendable { - // The name of the client as defined by the client. - public var name: String - - /// The client's version as defined by the client. - public var version: String? - - public init(name: String, version: String? = nil) { - self.name = name - self.version = version - } - } - - public static let method: String = "initialize" - public typealias Response = InitializeResult - - /// The process identifier (pid) of the process that started the LSP server, or nil if the server - /// was started by e.g. a user shell and should not be monitored. - /// - /// If the client process dies, the server should exit. - public var processId: Int? = nil - - /// Information about the client - public var clientInfo: ClientInfo? = nil - - /// The locale the client is currently showing the user interface - /// in. This must not necessarily be the locale of the operating - /// system. - /// - /// Uses IETF language tags as the value's syntax - /// (See https://en.wikipedia.org/wiki/IETF_language_tag) - public var locale: String? = nil - - /// The workspace path, or nil if no workspace is open. - /// - /// - Note: deprecated in favour of `rootURI`. - public var rootPath: String? = nil - - /// The workspace URI, or nil if no workspace is open. - /// - /// Takes precedence over the deprecated `rootPath`. - public var rootURI: DocumentURI? - - /// User-provided options. - public var initializationOptions: LSPAny? = nil - - /// The capabilities provided by the client editor. - public var capabilities: ClientCapabilities - - /// Whether to enable tracing. - public var trace: Tracing? = .off - - /// The workspace folders configured, if the client supports multiple workspace folders. - public var workspaceFolders: [WorkspaceFolder]? - - public init( - processId: Int? = nil, - clientInfo: ClientInfo? = nil, - locale: String? = nil, - rootPath: String? = nil, - rootURI: DocumentURI?, - initializationOptions: LSPAny? = nil, - capabilities: ClientCapabilities, - trace: Tracing = .off, - workspaceFolders: [WorkspaceFolder]? - ) { - self.processId = processId - self.clientInfo = clientInfo - self.locale = locale - self.rootPath = rootPath - self.rootURI = rootURI - self.initializationOptions = initializationOptions - self.capabilities = capabilities - self.trace = trace - self.workspaceFolders = workspaceFolders - } -} - -extension InitializeRequest: Codable { - private enum CodingKeys: String, CodingKey { - case processId - case clientInfo - case locale - case rootPath - case rootURI = "rootUri" - case initializationOptions - case capabilities - case trace - case workspaceFolders - } -} - -/// The server capabilities returned from the initialize request. -public struct InitializeResult: ResponseType, Hashable { - - /// The capabilities of the language server. - public var capabilities: ServerCapabilities - - public init(capabilities: ServerCapabilities) { - self.capabilities = capabilities - } -} diff --git a/Sources/LanguageServerProtocol/Requests/InlayHintRefreshRequest.swift b/Sources/LanguageServerProtocol/Requests/InlayHintRefreshRequest.swift deleted file mode 100644 index b76261b83..000000000 --- a/Sources/LanguageServerProtocol/Requests/InlayHintRefreshRequest.swift +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct InlayHintRefreshRequest: RequestType { - public static let method: String = "workspace/inlayHint/refresh" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/InlayHintRequest.swift b/Sources/LanguageServerProtocol/Requests/InlayHintRequest.swift deleted file mode 100644 index be93611eb..000000000 --- a/Sources/LanguageServerProtocol/Requests/InlayHintRequest.swift +++ /dev/null @@ -1,38 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for inline annotations to be displayed in the editor. -/// -/// - Parameters: -/// - textDocument: The document for which to provide the inlay hints. -/// -/// - Returns: InlayHints for the entire document -public struct InlayHintRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/inlayHint" - public typealias Response = [InlayHint] - - /// The document for which to provide the inlay hints. - public var textDocument: TextDocumentIdentifier - - /// The range the inlay hints are requested for. If nil, - /// hints for the entire document are requested. - @CustomCodable - public var range: Range? - - public init( - textDocument: TextDocumentIdentifier, - range: Range? = nil - ) { - self.textDocument = textDocument - self._range = CustomCodable(wrappedValue: range) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/InlayHintResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/InlayHintResolveRequest.swift deleted file mode 100644 index 7646eeb25..000000000 --- a/Sources/LanguageServerProtocol/Requests/InlayHintResolveRequest.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct InlayHintResolveRequest: RequestType { - public static let method: String = "inlayHint/resolve" - public typealias Response = InlayHint - - public var inlayHint: InlayHint - - public init(inlayHint: InlayHint) { - self.inlayHint = inlayHint - } - - public init(from decoder: Decoder) throws { - self.inlayHint = try InlayHint(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try inlayHint.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/InlineValueRefreshRequest.swift b/Sources/LanguageServerProtocol/Requests/InlineValueRefreshRequest.swift deleted file mode 100644 index b479a1724..000000000 --- a/Sources/LanguageServerProtocol/Requests/InlineValueRefreshRequest.swift +++ /dev/null @@ -1,18 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct InlineValueRefreshRequest: RequestType { - public static let method: String = "workspace/inlineValue/refresh" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/InlineValueRequest.swift b/Sources/LanguageServerProtocol/Requests/InlineValueRequest.swift deleted file mode 100644 index ae0ef4788..000000000 --- a/Sources/LanguageServerProtocol/Requests/InlineValueRequest.swift +++ /dev/null @@ -1,152 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct InlineValueContext: Codable, Hashable, Sendable { - /// The stack frame (as a DAP Id) where the execution has stopped. - public var frameId: Int - - /// The document range where execution has stopped. - /// Typically the end position of the range denotes the line where the - /// inline values are shown. - @CustomCodable - public var stoppedLocation: Range - - public init(frameId: Int, stoppedLocation: Range) { - self.frameId = frameId - self.stoppedLocation = stoppedLocation - } -} - -/// The inline value request is sent from the client to the server to compute inline values for a given text document that may be rendered in the editor at the end of lines. -public struct InlineValueRequest: TextDocumentRequest { - public static let method: String = "textDocument/inlineValue" - public typealias Response = [InlineValue]? - - /// The text document. - public var textDocument: TextDocumentIdentifier - - /// The document range for which inline values should be computed. - @CustomCodable - public var range: Range - - /// Additional information about the context in which inline values were - /// requested. - public var context: InlineValueContext - - public init(textDocument: TextDocumentIdentifier, range: Range, context: InlineValueContext) { - self.textDocument = textDocument - self.range = range - self.context = context - } -} - -/// Provide inline value as text. -public struct InlineValueText: Codable, Hashable, Sendable { - /// The document range for which the inline value applies. - @CustomCodable - public var range: Range - - /// The text of the inline value. - public var text: String - - public init(range: Range, text: String) { - self.range = range - self.text = text - } -} - -/// Provide inline value through a variable lookup. -/// -/// If only a range is specified, the variable name will be extracted from -/// the underlying document. -/// -/// An optional variable name can be used to override the extracted name. -public struct InlineValueVariableLookup: Codable, Hashable, Sendable { - /// The document range for which the inline value applies. - /// The range is used to extract the variable name from the underlying - /// document. - @CustomCodable - public var range: Range - - /// If specified the name of the variable to look up. - public var variableName: String? - - /// How to perform the lookup. - public var caseSensitiveLookup: Bool - - public init(range: Range, variableName: String? = nil, caseSensitiveLookup: Bool) { - self.range = range - self.variableName = variableName - self.caseSensitiveLookup = caseSensitiveLookup - } -} - -/// Provide an inline value through an expression evaluation. -/// -/// If only a range is specified, the expression will be extracted from the -/// underlying document. -/// -/// An optional expression can be used to override the extracted expression. -public struct InlineValueEvaluatableExpression: Codable, Hashable, Sendable { - /// The document range for which the inline value applies. - /// The range is used to extract the evaluatable expression from the - /// underlying document. - @CustomCodable - public var range: Range - - /// If specified the expression overrides the extracted expression. - public var expression: String? - - public init(range: Range, expression: String? = nil) { - self.range = range - self.expression = expression - } -} - -/// Inline value information can be provided by different means: -/// - directly as a text value (class InlineValueText). -/// - as a name to use for a variable lookup (class InlineValueVariableLookup) -/// - as an evaluatable expression (class InlineValueEvaluatableExpression) -/// The InlineValue types combines all inline value types into one type. -public enum InlineValue: ResponseType, Hashable, Sendable { - case text(InlineValueText) - case variableLookup(InlineValueVariableLookup) - case evaluatableExpression(InlineValueEvaluatableExpression) - - public init(from decoder: Decoder) throws { - if let text = try? InlineValueText(from: decoder) { - self = .text(text) - } else if let variableLookup = try? InlineValueVariableLookup(from: decoder) { - self = .variableLookup(variableLookup) - } else if let evaluatableExpression = try? InlineValueEvaluatableExpression(from: decoder) { - self = .evaluatableExpression(evaluatableExpression) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: - "Expected InlineValueText, InlineValueEvaluatableExpression or InlineValueEvaluatableExpression" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .text(let text): - try text.encode(to: encoder) - case .variableLookup(let variableLookup): - try variableLookup.encode(to: encoder) - case .evaluatableExpression(let evaluatableExpression): - try evaluatableExpression.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/Requests/IsIndexingRequest.swift b/Sources/LanguageServerProtocol/Requests/IsIndexingRequest.swift deleted file mode 100644 index ca4739189..000000000 --- a/Sources/LanguageServerProtocol/Requests/IsIndexingRequest.swift +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct IsIndexingRequest: RequestType { - public static let method: String = "sourceKit/_isIndexing" - public typealias Response = IsIndexingResponse - - public init() {} -} - -public struct IsIndexingResponse: ResponseType { - /// Whether SourceKit-LSP is currently performing an indexing task. - public var indexing: Bool - - public init(indexing: Bool) { - self.indexing = indexing - } -} diff --git a/Sources/LanguageServerProtocol/Requests/LinkedEditingRangeRequest.swift b/Sources/LanguageServerProtocol/Requests/LinkedEditingRangeRequest.swift deleted file mode 100644 index 85a70d77f..000000000 --- a/Sources/LanguageServerProtocol/Requests/LinkedEditingRangeRequest.swift +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct LinkedEditingRangeRequest: TextDocumentRequest { - public static let method: String = "textDocument/linkedEditingRange" - public typealias Response = LinkedEditingRanges? - - /// The document in which the given symbol is located. - public var textDocument: TextDocumentIdentifier - - /// The document location of a given symbol. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -public struct LinkedEditingRanges: ResponseType { - /// A list of ranges that can be renamed together. The ranges must have - /// identical length and contain identical text content. The ranges cannot - /// overlap. - @CustomCodable - public var ranges: [Range] - - /// An optional word pattern (regular expression) that describes valid - /// contents for the given ranges. If no pattern is provided, the client - /// configuration's word pattern will be used. - public var wordPattern: String? - - public init(ranges: [Range], wordPattern: String? = nil) { - self.ranges = ranges - self.wordPattern = wordPattern - } -} diff --git a/Sources/LanguageServerProtocol/Requests/MonikersRequest.swift b/Sources/LanguageServerProtocol/Requests/MonikersRequest.swift deleted file mode 100644 index b83b0b6ab..000000000 --- a/Sources/LanguageServerProtocol/Requests/MonikersRequest.swift +++ /dev/null @@ -1,93 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct MonikersRequest: TextDocumentRequest { - public static let method: String = "textDocument/moniker" - public typealias Response = [Moniker]? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -/// Moniker definition to match LSIF 0.5 moniker definition. -public struct Moniker: ResponseType, Hashable { - /// Moniker uniqueness level to define scope of the moniker. - public struct UniquenessLevel: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// The moniker is only unique inside a document - public static let document = UniquenessLevel(rawValue: "document") - - /// The moniker is unique inside a project for which a dump got created - public static let project = UniquenessLevel(rawValue: "project") - - /// The moniker is unique inside the group to which a project belongs - public static let group = UniquenessLevel(rawValue: "group") - - /// The moniker is unique inside the moniker scheme. - public static let scheme = UniquenessLevel(rawValue: "scheme") - - /// The moniker is globally unique - public static let global = UniquenessLevel(rawValue: "global") - } - - /// The moniker kind. - public struct Kind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// The moniker represent a symbol that is imported into a project - public static let `import` = Kind(rawValue: "import") - - /// The moniker represents a symbol that is exported from a project - public static let export = Kind(rawValue: "export") - - /// The moniker represents a symbol that is local to a project (e.g. a local - /// variable of a function, a class not visible outside the project, ...) - public static let local = Kind(rawValue: "local") - } - - /// The scheme of the moniker. For example tsc or .Net - public var scheme: String - - /// The identifier of the moniker. The value is opaque in LSIF however - /// schema owners are allowed to define the structure if they want. - public var identifier: String - - /// The scope in which the moniker is unique - public var unique: UniquenessLevel - - /// The moniker kind if known. - public var kind: Kind? - - public init(scheme: String, identifier: String, unique: UniquenessLevel, kind: Kind? = nil) { - self.scheme = scheme - self.identifier = identifier - self.unique = unique - self.kind = kind - } -} diff --git a/Sources/LanguageServerProtocol/Requests/OutputPathsRequest.swift b/Sources/LanguageServerProtocol/Requests/OutputPathsRequest.swift deleted file mode 100644 index d7e498c32..000000000 --- a/Sources/LanguageServerProtocol/Requests/OutputPathsRequest.swift +++ /dev/null @@ -1,39 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the client to the server to retrieve the output paths of a target (see the `buildTarget/outputPaths` -/// BSP request). -/// -/// **(LSP Extension)**. -public struct OutputPathsRequest: RequestType, Hashable { - public static let method: String = "workspace/_outputPaths" - public typealias Response = OutputPathsResponse - - /// The target whose output file paths to get. - public var target: DocumentURI - - /// The URI of the workspace to which the target belongs. - public var workspace: DocumentURI - - public init(target: DocumentURI, workspace: DocumentURI) { - self.target = target - self.workspace = workspace - } -} -public struct OutputPathsResponse: ResponseType, Hashable { - /// The output paths for all source files in the target - public var outputPaths: [String] - - public init(outputPaths: [String]) { - self.outputPaths = outputPaths - } -} diff --git a/Sources/LanguageServerProtocol/Requests/PeekDocumentsRequest.swift b/Sources/LanguageServerProtocol/Requests/PeekDocumentsRequest.swift deleted file mode 100644 index 7303934ff..000000000 --- a/Sources/LanguageServerProtocol/Requests/PeekDocumentsRequest.swift +++ /dev/null @@ -1,57 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the server to the client to show the given documents in a "peeked" editor **(LSP Extension)** -/// -/// This request is handled by the client to show the given documents in a -/// "peeked" editor (i.e. inline with / inside the editor canvas). This is -/// similar to VS Code's built-in "editor.action.peekLocations" command. -/// -/// - Parameters: -/// - uri: The DocumentURI of the text document in which to show the "peeked" editor -/// - position: The position in the given text document in which to show the "peeked editor" -/// - locations: The DocumentURIs of documents to appear inside the "peeked" editor -/// -/// - Returns: `PeekDocumentsResponse` which indicates the `success` of the request. -/// -/// ### LSP Extension -/// -/// This request is an extension to LSP supported by SourceKit-LSP. -/// It requires the experimental client capability `"workspace/peekDocuments"` to use. -/// It also needs the client to handle the request and present the "peeked" editor. -public struct PeekDocumentsRequest: RequestType { - public static let method: String = "workspace/peekDocuments" - public typealias Response = PeekDocumentsResponse - - public var uri: DocumentURI - public var position: Position - public var locations: [DocumentURI] - - public init( - uri: DocumentURI, - position: Position, - locations: [DocumentURI] - ) { - self.uri = uri - self.position = position - self.locations = locations - } -} - -/// Response to indicate the `success` of the `PeekDocumentsRequest` -public struct PeekDocumentsResponse: ResponseType { - public var success: Bool - - public init(success: Bool) { - self.success = success - } -} diff --git a/Sources/LanguageServerProtocol/Requests/PrepareRenameRequest.swift b/Sources/LanguageServerProtocol/Requests/PrepareRenameRequest.swift deleted file mode 100644 index a5e7ffeae..000000000 --- a/Sources/LanguageServerProtocol/Requests/PrepareRenameRequest.swift +++ /dev/null @@ -1,91 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to test the validity of a rename operation at the given location. -/// -/// Looks up the symbol at the given position and returns the range of the symbol the user is renaming, -/// or null if there is no symbol to be renamed at the given position -/// -/// Servers that provide rename preparation should set `prepareProvider` to true in the `renameProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: A range for the symbol, and optionally a placeholder text of the string content to be renamed. -public struct PrepareRenameRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/prepareRename" - public typealias Response = PrepareRenameResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -public struct PrepareRenameResponse: ResponseType, Hashable { - /// The range of the symbol - @CustomCodable - public var range: Range - - /// A placeholder text of the string content to be renamed - public var placeholder: String? - - public init(range: Range, placeholder: String? = nil) { - self.range = range - self.placeholder = placeholder - } - - public init(from decoder: Decoder) throws { - // Try decoding as PrepareRenameResponse - do { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.range = try container.decode(PositionRange.self, forKey: .range).wrappedValue - self.placeholder = try container.decode(String.self, forKey: .placeholder) - return - } catch {} - - // Try decoding as PositionRange - do { - self.range = try PositionRange(from: decoder).wrappedValue - self.placeholder = nil - return - } catch {} - - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected PrepareRenameResponse or PositionRange" - ) - throw DecodingError.dataCorrupted(context) - } - - public func encode(to encoder: Encoder) throws { - if let placeholder = placeholder { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(_range, forKey: .range) - try container.encode(placeholder, forKey: .placeholder) - } else { - try _range.encode(to: encoder) - } - } - - private enum CodingKeys: String, CodingKey { - case range - case placeholder - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ReferencesRequest.swift b/Sources/LanguageServerProtocol/Requests/ReferencesRequest.swift deleted file mode 100644 index 7211dcf8d..000000000 --- a/Sources/LanguageServerProtocol/Requests/ReferencesRequest.swift +++ /dev/null @@ -1,52 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to find all references to the symbol at the given location across the workspace. -/// -/// Looks up the symbol at the given position and returns a list of all references to that symbol -/// across the whole workspace. Unlike `documentHighlight`, this is not scoped to a single document. -/// -/// Servers that provide document highlights should set the`referencesProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// - includeDeclaration: Whether to include the declaration in the list of symbols. -/// -/// - Returns: An array of locations, one for each reference. -public struct ReferencesRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/references" - public typealias Response = [Location] - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public var context: ReferencesContext - - public init(textDocument: TextDocumentIdentifier, position: Position, context: ReferencesContext) { - self.textDocument = textDocument - self.position = position - self.context = context - } -} - -public struct ReferencesContext: Codable, Hashable, Sendable { - /// Whether to include the declaration in the list of symbols, or just the references. - public var includeDeclaration: Bool - - public init(includeDeclaration: Bool) { - self.includeDeclaration = includeDeclaration - } -} diff --git a/Sources/LanguageServerProtocol/Requests/RegisterCapabilityRequest.swift b/Sources/LanguageServerProtocol/Requests/RegisterCapabilityRequest.swift deleted file mode 100644 index 9d80fb305..000000000 --- a/Sources/LanguageServerProtocol/Requests/RegisterCapabilityRequest.swift +++ /dev/null @@ -1,61 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// Request sent from the server to the client to dynamically register for a new capability on the -/// client side. -/// -/// Note that not all clients support dynamic registration and clients may provide dynamic -/// registration support for some capabilities but not others. -/// -/// Servers must not register the same capability both statically through the initialization result -/// and dynamically. Servers that want to support both should check the client capabilities and only -/// register the capability statically if the client doesn't support dynamic registration for that -/// capability. -public struct RegisterCapabilityRequest: RequestType, Hashable { - public static let method: String = "client/registerCapability" - public typealias Response = VoidResponse - - /// Capability registrations. - public var registrations: [CapabilityRegistration] - - public init(registrations: [CapabilityRegistration]) { - self.registrations = registrations - } -} - -/// General parameters to register a capability. -public struct CapabilityRegistration: Codable, Hashable, Sendable { - /// The id used to register the capability which may be used to unregister support. - public var id: String - - /// The method/capability to register for. - public var method: String - - /// Options necessary for this registration. - public var registerOptions: LSPAny? - - public init(id: String, method: String, registerOptions: LSPAny?) { - self.id = id - self.method = method - self.registerOptions = registerOptions - } - - /// Create a new `CapabilityRegistration` with a randomly generated id. Save - /// the generated id if you wish to unregister the given registration. - public init(method: String, registerOptions: LSPAny?) { - self.id = UUID().uuidString - self.method = method - self.registerOptions = registerOptions - } -} diff --git a/Sources/LanguageServerProtocol/Requests/RenameRequest.swift b/Sources/LanguageServerProtocol/Requests/RenameRequest.swift deleted file mode 100644 index 624b02e53..000000000 --- a/Sources/LanguageServerProtocol/Requests/RenameRequest.swift +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to compute a workspace range to rename a symbol. The change is then performed client side. -/// -/// Looks up the symbol at the given position and returns the range of the symbol the user is renaming, -/// or null if there is no symbol to be renamed at the given position -/// -/// Servers that allow renaming should set the `renameProvider` server capability. -/// -/// - Parameters: -/// - textDocument: The document in which the selected symbol is. -/// - position: The document location at which the selected symbol is. -/// - newName: The new name of the symbol. -/// -/// - Returns: A workspace edit -public struct RenameRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/rename" - public typealias Response = WorkspaceEdit? - - /// The document in which the selected symbol is. - public var textDocument: TextDocumentIdentifier - - /// The document location at which the selected symbol is. - public var position: Position - - /// The new name of the symbol. If the given name is not valid the request must return - /// a ResponseError with an appropriate message set. - public var newName: String - - public init(textDocument: TextDocumentIdentifier, position: Position, newName: String) { - self.textDocument = textDocument - self.position = position - self.newName = newName - } -} diff --git a/Sources/LanguageServerProtocol/Requests/SelectionRangeRequest.swift b/Sources/LanguageServerProtocol/Requests/SelectionRangeRequest.swift deleted file mode 100644 index 838172821..000000000 --- a/Sources/LanguageServerProtocol/Requests/SelectionRangeRequest.swift +++ /dev/null @@ -1,76 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct SelectionRangeRequest: TextDocumentRequest { - public static let method: String = "textDocument/selectionRange" - public typealias Response = [SelectionRange] - - /// The text document. - public var textDocument: TextDocumentIdentifier - - /// The positions inside the text document. - public var positions: [Position] - - public init(textDocument: TextDocumentIdentifier, positions: [Position]) { - self.textDocument = textDocument - self.positions = positions - } -} - -public struct SelectionRange: ResponseType, Codable, Hashable { - /// Indirect reference to a `SelectionRange`. - final class SelectionRangeBox: Codable, Hashable, Sendable { - let selectionRange: SelectionRange - - init(selectionRange: SelectionRange) { - self.selectionRange = selectionRange - } - - init(from decoder: Decoder) throws { - self.selectionRange = try SelectionRange(from: decoder) - } - - func encode(to encoder: Encoder) throws { - try selectionRange.encode(to: encoder) - } - - static func == (lhs: SelectionRange.SelectionRangeBox, rhs: SelectionRange.SelectionRangeBox) -> Bool { - return lhs.selectionRange == rhs.selectionRange - } - - func hash(into hasher: inout Hasher) { - selectionRange.hash(into: &hasher) - } - } - - enum CodingKeys: String, CodingKey { - case range - case _parent = "parent" - } - - /// The range of this selection range. - @CustomCodable - public var range: Range - - /// The parent selection range containing this range. Therefore - /// `parent.range` must contain `this.range`. - private var _parent: SelectionRangeBox? - - public var parent: SelectionRange? { - return _parent?.selectionRange - } - - public init(range: Range, parent: SelectionRange? = nil) { - self.range = range - self._parent = parent.map(SelectionRangeBox.init) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/SetOptionsRequest.swift b/Sources/LanguageServerProtocol/Requests/SetOptionsRequest.swift deleted file mode 100644 index aa59284d4..000000000 --- a/Sources/LanguageServerProtocol/Requests/SetOptionsRequest.swift +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// New request to modify runtime options of SourceKit-LSP. -// -/// Any options not specified in this request will be left as-is. -public struct SetOptionsRequest: RequestType { - public static let method: String = "workspace/_setOptions" - public typealias Response = VoidResponse - - /// `true` to pause background indexing or `false` to resume background indexing. - public var backgroundIndexingPaused: Bool? - - public init(backgroundIndexingPaused: Bool?) { - self.backgroundIndexingPaused = backgroundIndexingPaused - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ShowDocumentRequest.swift b/Sources/LanguageServerProtocol/Requests/ShowDocumentRequest.swift deleted file mode 100644 index c40139ed9..000000000 --- a/Sources/LanguageServerProtocol/Requests/ShowDocumentRequest.swift +++ /dev/null @@ -1,52 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the server to the client to show a document on the client -/// side. -public struct ShowDocumentRequest: RequestType { - public static let method: String = "window/showDocument" - public typealias Response = ShowDocumentResponse - - /// The uri to show. - public var uri: DocumentURI - - /// An optional boolean indicates to show the resource in an external - /// program. To show, for example, `https://www.swift.org/ in the default WEB - /// browser set `external` to `true`. - public var external: Bool? - - /// An optional boolean to indicate whether the editor showing the document - /// should take focus or not. Clients might ignore this property if an - /// external program is started. - public var takeFocus: Bool? - - /// An optional selection range if the document is a text document. Clients - /// might ignore the property if an external program is started or the file - /// is not a text file. - public var selection: Range? - - public init(uri: DocumentURI, external: Bool? = nil, takeFocus: Bool? = nil, selection: Range? = nil) { - self.uri = uri - self.external = external - self.takeFocus = takeFocus - self.selection = selection - } -} - -public struct ShowDocumentResponse: Codable, Hashable, ResponseType { - /// A boolean indicating if the show was successful. - public var success: Bool - - public init(success: Bool) { - self.success = success - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ShowMessageRequest.swift b/Sources/LanguageServerProtocol/Requests/ShowMessageRequest.swift deleted file mode 100644 index 3b7334d46..000000000 --- a/Sources/LanguageServerProtocol/Requests/ShowMessageRequest.swift +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the server containing a message for the client to display. -/// -/// - Parameters: -/// - type: The kind of message. -/// - message: The contents of the message. -/// - actions: Action items which the user may select (up to 1). -/// -/// - Returns: The action selected by the user, if any. -public struct ShowMessageRequest: RequestType, Hashable { - public static let method: String = "window/showMessageRequest" - public typealias Response = MessageActionItem? - - /// The kind of message. - public var type: WindowMessageType - - /// The contents of the message. - public var message: String - - /// The action items to present with the message. - public var actions: [MessageActionItem]? - - public init( - type: WindowMessageType, - message: String, - actions: [MessageActionItem]? - ) { - self.type = type - self.message = message - self.actions = actions - } -} - -/// Message action item that the user may select. -public struct MessageActionItem: ResponseType, Hashable { - - /// The title of the item. - public var title: String - - public init(title: String) { - self.title = title - } -} diff --git a/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift b/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift deleted file mode 100644 index 036aa020f..000000000 --- a/Sources/LanguageServerProtocol/Requests/ShutdownRequest.swift +++ /dev/null @@ -1,34 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request indicating the server should start shutting down. -/// -/// The server should cleanup any state that it needs to, but not exit (otherwise the response might -/// not reach the client). See `Exit`. -/// -/// - Returns: Void. -public struct ShutdownRequest: RequestType, Hashable { - public static let method: String = "shutdown" - - public struct Response: ResponseType, Equatable { - public init() {} - - public init(from decoder: any Decoder) throws {} - - public func encode(to encoder: any Encoder) throws { - var container = encoder.singleValueContainer() - try container.encodeNil() - } - } - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/SignatureHelpRequest.swift b/Sources/LanguageServerProtocol/Requests/SignatureHelpRequest.swift deleted file mode 100644 index 5abd1e87a..000000000 --- a/Sources/LanguageServerProtocol/Requests/SignatureHelpRequest.swift +++ /dev/null @@ -1,211 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct SignatureHelpRequest: TextDocumentRequest { - public static let method: String = "textDocument/signatureHelp" - public typealias Response = SignatureHelp? - - /// The document in which the given symbol is located. - public var textDocument: TextDocumentIdentifier - - /// The document location of a given symbol. - public var position: Position - - /// The signature help context. This is only available if the client - /// specifies to send this using the client capability - /// `textDocument.signatureHelp.contextSupport === true` - public var context: SignatureHelpContext? - - public init(textDocument: TextDocumentIdentifier, position: Position, context: SignatureHelpContext? = nil) { - self.textDocument = textDocument - self.position = position - self.context = context - } -} - -/// How a signature help was triggered. -public struct SignatureHelpTriggerKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Signature help was invoked manually by the user or by a command. - public static let invoked = SignatureHelpTriggerKind(rawValue: 1) - - /// Signature help was triggered by a trigger character. - public static let triggerCharacter = SignatureHelpTriggerKind(rawValue: 2) - - /// Signature help was triggered by the cursor moving or by the document - /// content changing. - public static let contentChange = SignatureHelpTriggerKind(rawValue: 3) -} - -/// Additional information about the context in which a signature help request -/// was triggered. -public struct SignatureHelpContext: Codable, Hashable, Sendable { - /// Action that caused signature help to be triggered. - public var triggerKind: SignatureHelpTriggerKind - - /// Character that caused signature help to be triggered. - /// - /// This is undefined when triggerKind !== - /// SignatureHelpTriggerKind.TriggerCharacter - public var triggerCharacter: String? - - /// `true` if signature help was already showing when it was triggered. - /// - /// Retriggers occur when the signature help is already active and can be - /// caused by actions such as typing a trigger character, a cursor move, or - /// document content changes. - public var isRetrigger: Bool - - /// The currently active `SignatureHelp`. - /// - /// The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field - /// updated based on the user navigating through available signatures. - public var activeSignatureHelp: SignatureHelp? - - public init( - triggerKind: SignatureHelpTriggerKind, - triggerCharacter: String? = nil, - isRetrigger: Bool, - activeSignatureHelp: SignatureHelp? = nil - ) { - self.triggerKind = triggerKind - self.triggerCharacter = triggerCharacter - self.isRetrigger = isRetrigger - self.activeSignatureHelp = activeSignatureHelp - } -} - -/// Signature help represents the signature of something -/// callable. There can be multiple signature but only one -/// active and only one active parameter. -public struct SignatureHelp: ResponseType, Hashable { - /// One or more signatures. If no signatures are available the signature help - /// request should return `null`. - public var signatures: [SignatureInformation] - - /// The active signature. If omitted or the value lies outside the - /// range of `signatures` the value defaults to zero or is ignore if - /// the `SignatureHelp` as no signatures. - /// - /// Whenever possible implementors should make an active decision about - /// the active signature and shouldn't rely on a default value. - /// - /// In future version of the protocol this property might become - /// mandatory to better express this. - public var activeSignature: Int? - - /// The active parameter of the active signature. If omitted or the value - /// lies outside the range of `signatures[activeSignature].parameters` - /// defaults to 0 if the active signature has parameters. If - /// the active signature has no parameters it is ignored. - /// In future version of the protocol this property might become - /// mandatory to better express the active parameter if the - /// active signature does have any. - public var activeParameter: Int? - - public init(signatures: [SignatureInformation], activeSignature: Int? = nil, activeParameter: Int? = nil) { - self.signatures = signatures - self.activeSignature = activeSignature - self.activeParameter = activeParameter - } -} - -/// Represents the signature of something callable. A signature -/// can have a label, like a function-name, a doc-comment, and -/// a set of parameters. -public struct SignatureInformation: Codable, Hashable, Sendable { - /// The label of this signature. Will be shown in - /// the UI. - public var label: String - - /// The human-readable doc-comment of this signature. Will be shown - /// in the UI but can be omitted. - public var documentation: StringOrMarkupContent? - - /// The parameters of this signature. - public var parameters: [ParameterInformation]? - - /// The index of the active parameter. - /// - /// If provided, this is used in place of `SignatureHelp.activeParameter`. - public var activeParameter: Int? - - public init( - label: String, - documentation: StringOrMarkupContent? = nil, - parameters: [ParameterInformation]? = nil, - activeParameter: Int? = nil - ) { - self.label = label - self.documentation = documentation - self.parameters = parameters - self.activeParameter = activeParameter - } -} - -/// Represents a parameter of a callable-signature. A parameter can -/// have a label and a doc-comment. -public struct ParameterInformation: Codable, Hashable, Sendable { - public enum Label: Codable, Hashable, Sendable { - case string(String) - case offsets(start: Int, end: Int) - - public init(from decoder: Decoder) throws { - if let string = try? String(from: decoder) { - self = .string(string) - } else if let offsets = try? [Int](from: decoder), offsets.count == 2 { - self = .offsets(start: offsets[0], end: offsets[1]) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected String or an array containing two integers" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .string(let string): - try string.encode(to: encoder) - case .offsets(let start, let end): - try [start, end].encode(to: encoder) - } - } - } - - /// The label of this parameter information. - /// - /// Either a string or an inclusive start and exclusive end offsets within - /// its containing signature label. (see SignatureInformation.label). The - /// offsets are based on a UTF-16 string representation as `Position` and - /// `Range` does. - /// - /// *Note*: a label of type string should be a substring of its containing - /// signature label. Its intended use case is to highlight the parameter - /// label part in the `SignatureInformation.label`. - public var label: Label - - /// The human-readable doc-comment of this parameter. Will be shown - /// in the UI but can be omitted. - public var documentation: StringOrMarkupContent? - - public init(label: Label, documentation: StringOrMarkupContent? = nil) { - self.label = label - self.documentation = documentation - } -} diff --git a/Sources/LanguageServerProtocol/Requests/SourceKitOptionsRequest.swift b/Sources/LanguageServerProtocol/Requests/SourceKitOptionsRequest.swift deleted file mode 100644 index ef0052d05..000000000 --- a/Sources/LanguageServerProtocol/Requests/SourceKitOptionsRequest.swift +++ /dev/null @@ -1,111 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the client to the server to retrieve the compiler arguments that SourceKit-LSP uses to process the -/// document. -/// -/// This request does not require the document to be opened in SourceKit-LSP. This is also why it has the `workspace/` -/// instead of the `textDocument/` prefix. -/// -/// **(LSP Extension)**. -public struct SourceKitOptionsRequest: RequestType, Hashable { - public static let method: String = "workspace/_sourceKitOptions" - public typealias Response = SourceKitOptionsResponse - - /// The document to get options for - public var textDocument: TextDocumentIdentifier - - /// If specified, explicitly request the compiler arguments when interpreting the document in the context of the given - /// target. - /// - /// The target URI must match the URI that is used by the BSP server to identify the target. This option thus only - /// makes sense to specify if the client also controls the BSP server. - /// - /// When this is `nil`, SourceKit-LSP returns the compiler arguments it uses when the the document is opened in the - /// client, ie. it infers a canonical target for the document. - public var target: DocumentURI? - - /// Whether SourceKit-LSP should ensure that the document's target is prepared before returning build settings. - /// - /// There is a tradeoff whether the target should be prepared: Preparing a target may take significant time but if the - /// target is not prepared, the build settings might eg. refer to modules that haven't been built yet. - public var prepareTarget: Bool - - /// If set to `true` and build settings could not be determined within a timeout (see `buildSettingsTimeout` in the - /// SourceKit-LSP configuration file), this request returns fallback build settings. - /// - /// If set to `false` the request only finishes when build settings were provided by the build server. - public var allowFallbackSettings: Bool - - public init( - textDocument: TextDocumentIdentifier, - target: DocumentURI? = nil, - prepareTarget: Bool, - allowFallbackSettings: Bool - ) { - self.textDocument = textDocument - self.target = target - self.prepareTarget = prepareTarget - self.allowFallbackSettings = allowFallbackSettings - } -} - -/// The kind of options that were returned by the `workspace/_sourceKitOptions` request, ie. whether they are fallback -/// options or the real compiler options for the file. -public struct SourceKitOptionsKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// The SourceKit options are known to SourceKit-LSP and returned them. - public static let normal = SourceKitOptionsKind(rawValue: "normal") - - /// SourceKit-LSP was unable to determine the build settings for this file and synthesized fallback settings. - public static let fallback = SourceKitOptionsKind(rawValue: "fallback") -} - -public struct SourceKitOptionsResponse: ResponseType, Hashable { - /// The compiler options required for the requested file. - public var compilerArguments: [String] - - /// The working directory for the compile command. - public var workingDirectory: String? - - /// Whether SourceKit-LSP was able to determine the build settings or synthesized fallback settings. - public var kind: SourceKitOptionsKind - - /// - `true` If the request requested the file's target to be prepared and the target needed preparing - /// - `false` If the request requested the file's target to be prepared and the target was up to date - /// - `nil`: If the request did not request the file's target to be prepared or the target could not be prepared for - /// other reasons - public var didPrepareTarget: Bool? - - /// Additional data that the BSP server returned in the `textDocument/sourceKitOptions` BSP request. This data is not - /// interpreted by SourceKit-LSP. - public var data: LSPAny? - - public init( - compilerArguments: [String], - workingDirectory: String? = nil, - kind: SourceKitOptionsKind, - didPrepareTarget: Bool? = nil, - data: LSPAny? = nil - ) { - self.compilerArguments = compilerArguments - self.workingDirectory = workingDirectory - self.kind = kind - self.didPrepareTarget = didPrepareTarget - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/SymbolInfoRequest.swift b/Sources/LanguageServerProtocol/Requests/SymbolInfoRequest.swift deleted file mode 100644 index 217a7b5f4..000000000 --- a/Sources/LanguageServerProtocol/Requests/SymbolInfoRequest.swift +++ /dev/null @@ -1,159 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for semantic information about the symbol at a given location **(LSP Extension)**. -/// -/// This request looks up the symbol (if any) at a given text document location and returns -/// SymbolDetails for that location, including information such as the symbol's USR. The symbolInfo -/// request is not primarily designed for editors, but instead as an implementation detail of how -/// one LSP implementation (e.g. SourceKit) gets information from another (e.g. clangd) to use in -/// performing index queries or otherwise implementing the higher level requests such as definition. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: `[SymbolDetails]` for the given location, which may have multiple elements if there are -/// multiple references, or no elements if there is no symbol at the given location. -/// -/// ### LSP Extension -/// -/// This request is an extension to LSP supported by SourceKit-LSP and clangd. It does *not* require -/// any additional client or server capabilities to use. -public struct SymbolInfoRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/symbolInfo" - public typealias Response = [SymbolDetails] - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} - -/// Detailed information about a symbol, such as the response to a `SymbolInfoRequest` -/// **(LSP Extension)**. -public struct SymbolDetails: ResponseType, Hashable { - public struct ModuleInfo: Codable, Hashable, Sendable { - /// The name of the module in which the symbol is defined. - public let moduleName: String - - /// If the symbol is defined within a subgroup of a module, the name of the group. Otherwise `nil`. - public let groupName: String? - - public init(moduleName: String, groupName: String? = nil) { - self.moduleName = moduleName - self.groupName = groupName - } - } - - /// The name of the symbol, if any. - public var name: String? - - /// The name of the containing type for the symbol, if any. - /// - /// For example, in the following snippet, the `containerName` of `foo()` is `C`. - /// - /// ```c++ - /// class C { - /// void foo() {} - /// } - /// ``` - public var containerName: String? - - /// The USR of the symbol, if any. - public var usr: String? - - /// An opaque identifier in a format known only to clangd. - // public var id: String? - - /// Best known declaration or definition location without global knowledge. - /// - /// For a local or private variable, this is generally the canonical definition location - - /// appropriate as a response to a `textDocument/definition` request. For global symbols this is - /// the best known location within a single compilation unit. For example, in C++ this might be - /// the declaration location from a header as opposed to the definition in some other - /// translation unit. - public var bestLocalDeclaration: Location? = nil - - /// The kind of the symbol - public var kind: SymbolKind? - - /// Whether the symbol is a dynamic call for which it isn't known which method will be invoked at runtime. This is - /// the case for protocol methods and class functions. - /// - /// Optional because `clangd` does not return whether a symbol is dynamic. - public var isDynamic: Bool? - - /// Whether this symbol is defined in the SDK or standard library. - /// - /// This property only applies to Swift symbols. - public var isSystem: Bool? - - /// If the symbol is dynamic, the USRs of the types that might be called. - /// - /// This is relevant in the following cases - /// ```swift - /// class A { - /// func doThing() {} - /// } - /// class B: A {} - /// class C: B { - /// override func doThing() {} - /// } - /// class D: A { - /// override func doThing() {} - /// } - /// func test(value: B) { - /// value.doThing() - /// } - /// ``` - /// - /// The USR of the called function in `value.doThing` is `A.doThing` (or its - /// mangled form) but it can never call `D.doThing`. In this case, the - /// receiver USR would be `B`, indicating that only overrides of subtypes in - /// `B` may be called dynamically. - public var receiverUsrs: [String]? - - /// If the symbol is defined in a module that doesn't have source information associated with it, the name and group - /// and group name that defines this symbol. - /// - /// This property only applies to Swift symbols. - public var systemModule: ModuleInfo? - - public init( - name: String?, - containerName: String?, - usr: String?, - bestLocalDeclaration: Location?, - kind: SymbolKind?, - isDynamic: Bool?, - isSystem: Bool?, - receiverUsrs: [String]?, - systemModule: ModuleInfo? - ) { - self.name = name - self.containerName = containerName - self.usr = usr - self.bestLocalDeclaration = bestLocalDeclaration - self.kind = kind - self.isDynamic = isDynamic - self.isSystem = isSystem - self.receiverUsrs = receiverUsrs - self.systemModule = systemModule - } -} diff --git a/Sources/LanguageServerProtocol/Requests/SynchronizeRequest.swift b/Sources/LanguageServerProtocol/Requests/SynchronizeRequest.swift deleted file mode 100644 index 33ba049bb..000000000 --- a/Sources/LanguageServerProtocol/Requests/SynchronizeRequest.swift +++ /dev/null @@ -1,55 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the client to the server to wait for SourceKit-LSP to handle all ongoing requests and, optionally, wait -/// for background activity to finish. -/// -/// This method is intended to be used in automated environments which need to wait for background activity to finish -/// before executing requests that rely on that background activity to finish. Examples of such cases are: -/// - Automated tests that need to wait for background indexing to finish and then checking the result of request -/// results -/// - Automated tests that need to wait for requests like file changes to be handled and checking behavior after those -/// have been processed -/// - Code analysis tools that want to use SourceKit-LSP to gather information about the project but can only do so -/// after the index has been loaded -/// -/// Because this request waits for all other SourceKit-LSP requests to finish, it limits parallel request handling and -/// is ill-suited for any kind of interactive environment. In those environments, it is preferable to quickly give the -/// user a result based on the data that is available and (let the user) re-perform the action if the underlying index -/// data has changed. -public struct SynchronizeRequest: RequestType { - public static let method: String = "workspace/synchronize" - public typealias Response = VoidResponse - - /// Wait for the build server to have an up-to-date build graph by sending a `workspace/waitForBuildSystemUpdates` to - /// it. - /// This is implied by `index = true`. - /// - /// This option is experimental, guarded behind the `synchronize-for-build-system-updates` experimental feature, and - /// may be modified or removed in future versions of SourceKit-LSP without notice. Do not rely on it. - public var buildServerUpdates: Bool? - - /// Wait for the build server to update its internal mapping of copied files to their original location. - /// - /// This option is experimental, guarded behind the `synchronize-copy-file-map` experimental feature, and may be - /// modified or removed in future versions of SourceKit-LSP without notice. Do not rely on it. - public var copyFileMap: Bool? - - /// Wait for background indexing to finish and all index unit files to be loaded into indexstore-db. - public var index: Bool? - - public init(buildServerUpdates: Bool? = nil, copyFileMap: Bool? = nil, index: Bool? = nil) { - self.buildServerUpdates = buildServerUpdates - self.copyFileMap = copyFileMap - self.index = index - } -} diff --git a/Sources/LanguageServerProtocol/Requests/TriggerReindexRequest.swift b/Sources/LanguageServerProtocol/Requests/TriggerReindexRequest.swift deleted file mode 100644 index 9f99614db..000000000 --- a/Sources/LanguageServerProtocol/Requests/TriggerReindexRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Re-index all files open in the SourceKit-LSP server. -/// -/// Users should not need to rely on this request. The index should always be updated automatically in the background. -/// Having to invoke this request means there is a bug in SourceKit-LSP's automatic re-indexing. It does, however, offer -/// a workaround to re-index files when such a bug occurs where otherwise there would be no workaround. -/// -/// **LSP Extension** -public struct TriggerReindexRequest: RequestType { - public static let method: String = "workspace/triggerReindex" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/TypeDefinitionRequest.swift b/Sources/LanguageServerProtocol/Requests/TypeDefinitionRequest.swift deleted file mode 100644 index 80305babe..000000000 --- a/Sources/LanguageServerProtocol/Requests/TypeDefinitionRequest.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request to find the type definition(s) of the symbol at the given location. -/// -/// Looks up the symbol at the given position and returns a list of all type definitions of that -/// symbol across the whole workspace. -/// -/// Servers that provide document highlights should set the `textDocument.typeDefinition` server -/// capability. -/// -/// - Parameters: -/// - textDocument: The document in which to lookup the symbol location. -/// - position: The document location at which to lookup symbol information. -/// -/// - Returns: The location of the type definition(s). -public struct TypeDefinitionRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/typeDefinition" - public typealias Response = LocationsOrLocationLinksResponse? - - /// The document in which to lookup the symbol location. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to lookup symbol information. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/TypeHierarchyPrepareRequest.swift b/Sources/LanguageServerProtocol/Requests/TypeHierarchyPrepareRequest.swift deleted file mode 100644 index 3378e04d9..000000000 --- a/Sources/LanguageServerProtocol/Requests/TypeHierarchyPrepareRequest.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The type hierarchy request is sent from the client to the server to return a -/// type hierarchy for the language element of the given text document positions. -/// Will return nil if the server couldn’t infer a valid type from the position. -/// -/// The type hierarchy requests are executed in two steps: -/// 1. A type hierarchy item is resolved for the given text document position -/// (via `textDocument/prepareTypeHierarchy`) -/// 2. The supertype or subtype type hierarchy items are resolved for a type hierarchy item -/// (via `typeHierarchy/supertypes` or `typeHierarchy/subtypes`) -public struct TypeHierarchyPrepareRequest: TextDocumentRequest, Hashable { - public static let method: String = "textDocument/prepareTypeHierarchy" - public typealias Response = [TypeHierarchyItem]? - - /// The document in which to prepare the type hierarchy items. - public var textDocument: TextDocumentIdentifier - - /// The document location at which to prepare the type hierarchy items. - public var position: Position - - public init(textDocument: TextDocumentIdentifier, position: Position) { - self.textDocument = textDocument - self.position = position - } -} diff --git a/Sources/LanguageServerProtocol/Requests/TypeHierarchySubtypesRequest.swift b/Sources/LanguageServerProtocol/Requests/TypeHierarchySubtypesRequest.swift deleted file mode 100644 index a53305bca..000000000 --- a/Sources/LanguageServerProtocol/Requests/TypeHierarchySubtypesRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The request is sent from the client to the server to resolve the subtypes for -/// a given call hierarchy item. It is only issued if a server registers for the -/// `textDocument/prepareTypeHierarchy` request. -public struct TypeHierarchySubtypesRequest: RequestType { - public static let method: String = "typeHierarchy/subtypes" - public typealias Response = [TypeHierarchyItem]? - - public var item: TypeHierarchyItem - - public init(item: TypeHierarchyItem) { - self.item = item - } -} diff --git a/Sources/LanguageServerProtocol/Requests/TypeHierarchySupertypesRequest.swift b/Sources/LanguageServerProtocol/Requests/TypeHierarchySupertypesRequest.swift deleted file mode 100644 index 9239a914d..000000000 --- a/Sources/LanguageServerProtocol/Requests/TypeHierarchySupertypesRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The request is sent from the client to the server to resolve the supertypes for -/// a given call hierarchy item. It is only issued if a server registers for the -/// `textDocument/prepareTypeHierarchy` request. -public struct TypeHierarchySupertypesRequest: RequestType { - public static let method: String = "typeHierarchy/supertypes" - public typealias Response = [TypeHierarchyItem]? - - public var item: TypeHierarchyItem - - public init(item: TypeHierarchyItem) { - self.item = item - } -} diff --git a/Sources/LanguageServerProtocol/Requests/UnregisterCapabilityRequest.swift b/Sources/LanguageServerProtocol/Requests/UnregisterCapabilityRequest.swift deleted file mode 100644 index 078284e02..000000000 --- a/Sources/LanguageServerProtocol/Requests/UnregisterCapabilityRequest.swift +++ /dev/null @@ -1,48 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request sent from the server to the client to unregister a previously registered -/// capability. -public struct UnregisterCapabilityRequest: RequestType, Hashable { - public static let method: String = "client/unregisterCapability" - public typealias Response = VoidResponse - - /// Capabilities to unregister. - public var unregistrations: [Unregistration] - - public init(unregistrations: [Unregistration]) { - self.unregistrations = unregistrations - } -} - -extension UnregisterCapabilityRequest: Codable { - private enum CodingKeys: String, CodingKey { - /// This should correctly be named `unregistrations`. However changing this - /// is a breaking change and needs to wait until the 4.x LSP spec update. - case unregistrations = "unregisterations" - } -} - -/// General parameters to unregister a capability. -public struct Unregistration: Codable, Hashable, Sendable { - /// The id used to unregister the capability, usually provided through the - /// register request. - public var id: String - - /// The method/capability to unregister for. - public var method: String - - public init(id: String, method: String) { - self.id = id - self.method = method - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WillChangeFilesRequests.swift b/Sources/LanguageServerProtocol/Requests/WillChangeFilesRequests.swift deleted file mode 100644 index b2bd19f1a..000000000 --- a/Sources/LanguageServerProtocol/Requests/WillChangeFilesRequests.swift +++ /dev/null @@ -1,83 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Represents information on a file/folder create. -public struct FileCreate: Codable, Hashable, Sendable { - /// A file:// URI for the location of the file/folder being created. - public var uri: DocumentURI - - public init(uri: DocumentURI) { - self.uri = uri - } -} - -public struct WillCreateFilesRequest: RequestType { - public static let method: String = "workspace/willCreateFiles" - public typealias Response = WorkspaceEdit? - - /// An array of all files/folders created in this operation. - public var files: [FileCreate] - - public init(files: [FileCreate]) { - self.files = files - } -} - -/// Represents information on a file/folder rename. -public struct FileRename: Codable, Hashable, Sendable { - - /// A file:// URI for the original location of the file/folder being renamed. - public var oldUri: DocumentURI - - /// A file:// URI for the new location of the file/folder being renamed. - public var newUri: DocumentURI - - public init(oldUri: DocumentURI, newUri: DocumentURI) { - self.oldUri = oldUri - self.newUri = newUri - } -} - -public struct WillRenameFilesRequest: RequestType { - public static let method: String = "workspace/willRenameFiles" - public typealias Response = WorkspaceEdit? - - /// An array of all files/folders renamed in this operation. When a folder - /// is renamed, only the folder will be included, and not its children. - public var files: [FileRename] - - public init(files: [FileRename]) { - self.files = files - } -} - -/// Represents information on a file/folder delete. -public struct FileDelete: Codable, Hashable, Sendable { - /// A file:// URI for the location of the file/folder being deleted. - public var uri: DocumentURI - - public init(uri: DocumentURI) { - self.uri = uri - } -} - -public struct WillDeleteFilesRequest: RequestType { - public static let method: String = "workspace/willDeleteFiles" - public typealias Response = WorkspaceEdit? - - /// An array of all files/folders deleted in this operation. - public var files: [FileDelete] - - public init(files: [FileDelete]) { - self.files = files - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WillSaveWaitUntilTextDocumentRequest.swift b/Sources/LanguageServerProtocol/Requests/WillSaveWaitUntilTextDocumentRequest.swift deleted file mode 100644 index 88afefdfd..000000000 --- a/Sources/LanguageServerProtocol/Requests/WillSaveWaitUntilTextDocumentRequest.swift +++ /dev/null @@ -1,27 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The document will save request is sent from the client to the server before the document is actually saved. The request can return an array of TextEdits which will be applied to the text document before it is saved. Please note that clients might drop results if computing the text edits took too long or if a server constantly fails on this request. This is done to keep the save fast and reliable. If a server has registered for open / close events clients should ensure that the document is open before a willSaveWaitUntil notification is sent since clients can’t change the content of a file without ownership transferal. -public struct WillSaveWaitUntilTextDocumentRequest: TextDocumentRequest { - public static let method: String = "textDocument/willSaveWaitUntil" - public typealias Response = [TextEdit]? - - /// The document that will be saved. - public var textDocument: TextDocumentIdentifier - - public var reason: TextDocumentSaveReason - - public init(textDocument: TextDocumentIdentifier, reason: TextDocumentSaveReason) { - self.textDocument = textDocument - self.reason = reason - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceDiagnosticsRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceDiagnosticsRequest.swift deleted file mode 100644 index 863398ef7..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceDiagnosticsRequest.swift +++ /dev/null @@ -1,188 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A previous result id in a workspace pull request. -public struct PreviousResultId: Codable, Sendable { - /// The URI for which the client knows a result id. - public var uri: DocumentURI - - /// The value of the previous result id. - public var value: String - - public init(uri: DocumentURI, value: String) { - self.uri = uri - self.value = value - } -} - -public struct WorkspaceDiagnosticsRequest: RequestType { - public static let method: String = "workspace/diagnostic" - public typealias Response = WorkspaceDiagnosticReport - - /// The additional identifier provided during registration. - public var identifier: String? - - /// The currently known diagnostic reports with their - /// previous result ids. - public var previousResultIds: [PreviousResultId] - - public init(identifier: String? = nil, previousResultIds: [PreviousResultId]) { - self.identifier = identifier - self.previousResultIds = previousResultIds - } -} - -/// A workspace diagnostic report. -public struct WorkspaceDiagnosticReport: ResponseType { - public var items: [WorkspaceDocumentDiagnosticReport] - - public init(items: [WorkspaceDocumentDiagnosticReport]) { - self.items = items - } -} - -/// A full document diagnostic report for a workspace diagnostic result. -public struct WorkspaceFullDocumentDiagnosticReport: Codable, Hashable, Sendable { - /// An optional result id. If provided it will - /// be sent on the next diagnostic request for the - /// same document. - public var resultId: String? - - /// The actual items. - public var items: [Diagnostic] - - /// The URI for which diagnostic information is reported. - public var uri: DocumentURI - - /// The version number for which the diagnostics are reported. - /// If the document is not marked as open `null` can be provided. - public var version: Int? - - public init(resultId: String? = nil, items: [Diagnostic], uri: DocumentURI, version: Int? = nil) { - self.resultId = resultId - self.items = items - self.uri = uri - self.version = version - } - - enum CodingKeys: CodingKey { - case kind - case resultId - case items - case uri - case version - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(DocumentDiagnosticReportKind.self, forKey: .kind) - guard kind == .full else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of FullDocumentDiagnosticReport is not 'full'" - ) - } - self.resultId = try container.decodeIfPresent(String.self, forKey: .resultId) - self.items = try container.decode([Diagnostic].self, forKey: .items) - self.uri = try container.decode(DocumentURI.self, forKey: .uri) - self.version = try container.decodeIfPresent(Int.self, forKey: .version) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(DocumentDiagnosticReportKind.full, forKey: .kind) - try container.encodeIfPresent(self.resultId, forKey: .resultId) - try container.encode(self.items, forKey: .items) - try container.encode(self.uri, forKey: .uri) - try container.encodeIfPresent(self.version, forKey: .version) - } -} - -/// An unchanged document diagnostic report for a workspace diagnostic result. -public struct WorkspaceUnchangedDocumentDiagnosticReport: Codable, Hashable, Sendable { - /// A result id which will be sent on the next - /// diagnostic request for the same document. - public var resultId: String - - /// The URI for which diagnostic information is reported. - public var uri: DocumentURI - - /// The version number for which the diagnostics are reported. - /// If the document is not marked as open `null` can be provided. - public var version: Int? - - public init(resultId: String, uri: DocumentURI, version: Int? = nil) { - self.resultId = resultId - self.uri = uri - self.version = version - } - - enum CodingKeys: CodingKey { - case kind - case resultId - case uri - case version - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(DocumentDiagnosticReportKind.self, forKey: .kind) - guard kind == .unchanged else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of FullDocumentDiagnosticReport is not 'unchanged'" - ) - } - self.resultId = try container.decode(String.self, forKey: .resultId) - self.uri = try container.decode(DocumentURI.self, forKey: .uri) - self.version = try container.decodeIfPresent(Int.self, forKey: .version) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(DocumentDiagnosticReportKind.unchanged, forKey: .kind) - try container.encode(self.resultId, forKey: .resultId) - try container.encode(self.uri, forKey: .uri) - try container.encodeIfPresent(self.version, forKey: .version) - } -} - -/// A workspace diagnostic document report. -public enum WorkspaceDocumentDiagnosticReport: Codable, Hashable, Sendable { - case full(WorkspaceFullDocumentDiagnosticReport) - case unchanged(WorkspaceUnchangedDocumentDiagnosticReport) - - public init(from decoder: Decoder) throws { - if let full = try? WorkspaceFullDocumentDiagnosticReport(from: decoder) { - self = .full(full) - } else if let unchanged = try? WorkspaceUnchangedDocumentDiagnosticReport(from: decoder) { - self = .unchanged(unchanged) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected WorkspaceFullDocumentDiagnosticReport or WorkspaceUnchangedDocumentDiagnosticReport" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .full(let full): - try full.encode(to: encoder) - case .unchanged(let unchanged): - try unchanged.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceFoldersRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceFoldersRequest.swift deleted file mode 100644 index c3ea079b2..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceFoldersRequest.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request from the server for the set of currently open workspace folders. -/// -/// -/// Clients that support workspace folders should set the `workspaceFolders` client capability. -/// -/// - Returns: The set of currently open workspace folders. Returns nil if only a single file is -/// open. Returns an empty array if a workspace is open but no folders are configured. -public struct WorkspaceFoldersRequest: RequestType, Hashable { - public static let method: String = "workspace/workspaceFolders" - public typealias Response = [WorkspaceFolder]? - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceSemanticTokensRefreshRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceSemanticTokensRefreshRequest.swift deleted file mode 100644 index b5b3d280f..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceSemanticTokensRefreshRequest.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Sent from the server to the client. Servers can use this to ask clients to -/// refresh semantic tokens for editors for which this server provides semantic -/// tokens, useful in cases of project wide configuration changes. -public struct WorkspaceSemanticTokensRefreshRequest: RequestType, Hashable { - public static let method: String = "workspace/semanticTokens/refresh" - public typealias Response = VoidResponse - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolResolveRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolResolveRequest.swift deleted file mode 100644 index fd0b3be2b..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolResolveRequest.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct WorkspaceSymbolResolveRequest: RequestType { - public static let method: String = "workspaceSymbol/resolve" - public typealias Response = WorkspaceSymbol - - public var workspaceSymbol: WorkspaceSymbol - - public init(workspaceSymbol: WorkspaceSymbol) { - self.workspaceSymbol = workspaceSymbol - } - - public init(from decoder: Decoder) throws { - self.workspaceSymbol = try WorkspaceSymbol(from: decoder) - } - - public func encode(to encoder: Encoder) throws { - try self.workspaceSymbol.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolsRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolsRequest.swift deleted file mode 100644 index 5c8dc1368..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceSymbolsRequest.swift +++ /dev/null @@ -1,174 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Request for all symbols that match a certain query string. -/// -/// This request looks up the canonical occurrence of each symbol which has a name that contains the query string. -/// The list of symbol information is returned -/// -/// Servers that provide workspace symbol queries should set the `workspaceSymbolProvider` server capability. -/// -/// - Parameters: -/// - query: The string that should be looked for in symbols of the workspace. -/// -/// - Returns: Information about each symbol with a name that contains the query string -public struct WorkspaceSymbolsRequest: RequestType, Hashable { - - public static let method: String = "workspace/symbol" - public typealias Response = [WorkspaceSymbolItem]? - - /// The document in which to lookup the symbol location. - public var query: String - - public init(query: String) { - self.query = query - } -} - -public enum WorkspaceSymbolItem: ResponseType, Hashable { - case symbolInformation(SymbolInformation) - case workspaceSymbol(WorkspaceSymbol) - - public init(from decoder: Decoder) throws { - if let symbolInformation = try? SymbolInformation(from: decoder) { - self = .symbolInformation(symbolInformation) - } else if let workspaceSymbol = try? WorkspaceSymbol(from: decoder) { - self = .workspaceSymbol(workspaceSymbol) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected SymbolInformation or WorkspaceSymbol" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .symbolInformation(let symbolInformation): - try symbolInformation.encode(to: encoder) - case .workspaceSymbol(let workspaceSymbol): - try workspaceSymbol.encode(to: encoder) - } - } -} - -public struct SymbolInformation: Hashable, ResponseType { - public var name: String - - public var kind: SymbolKind - - public var tags: [SymbolTag]? - - public var deprecated: Bool? - - public var location: Location - - public var containerName: String? - - public init( - name: String, - kind: SymbolKind, - tags: [SymbolTag]? = nil, - deprecated: Bool? = nil, - location: Location, - containerName: String? = nil - ) { - self.name = name - self.kind = kind - self.tags = tags - self.deprecated = deprecated - self.location = location - self.containerName = containerName - } -} - -/// A special workspace symbol that supports locations without a range -public struct WorkspaceSymbol: ResponseType, Hashable { - public enum WorkspaceSymbolLocation: Codable, Hashable, Sendable { - public struct URI: Codable, Hashable, Sendable { - public var uri: DocumentURI - - public init(uri: DocumentURI) { - self.uri = uri - } - } - - case location(Location) - case uri(URI) - - public init(from decoder: Decoder) throws { - if let location = try? Location(from: decoder) { - self = .location(location) - } else if let uri = try? WorkspaceSymbolLocation.URI(from: decoder) { - self = .uri(uri) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected Location or object containing a URI" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .location(let location): - try location.encode(to: encoder) - case .uri(let uri): - try uri.encode(to: encoder) - } - } - } - - /// The name of this symbol. - public var name: String - - /// The kind of this symbol. - public var kind: SymbolKind - - /// Tags for this completion item. - public var tags: [SymbolTag]? - - /// The name of the symbol containing this symbol. This information is for - /// user interface purposes (e.g. to render a qualifier in the user interface - /// if necessary). It can't be used to re-infer a hierarchy for the document - /// symbols. - public var containerName: String? - - /// The location of this symbol. Whether a server is allowed to - /// return a location without a range depends on the client - /// capability `workspace.symbol.resolveSupport`. - /// - /// See also `SymbolInformation.location`. - public var location: WorkspaceSymbolLocation - - /// A data entry field that is preserved on a workspace symbol between a - /// workspace symbol request and a workspace symbol resolve request. - public var data: LSPAny? - - public init( - name: String, - kind: SymbolKind, - tags: [SymbolTag]? = nil, - containerName: String? = nil, - location: WorkspaceSymbolLocation, - data: LSPAny? = nil - ) { - self.name = name - self.kind = kind - self.tags = tags - self.containerName = containerName - self.location = location - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/Requests/WorkspaceTestsRequest.swift b/Sources/LanguageServerProtocol/Requests/WorkspaceTestsRequest.swift deleted file mode 100644 index 843b645ef..000000000 --- a/Sources/LanguageServerProtocol/Requests/WorkspaceTestsRequest.swift +++ /dev/null @@ -1,21 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A request that returns symbols for all the test classes and test methods within the current workspace. -/// -/// **(LSP Extension)** -public struct WorkspaceTestsRequest: RequestType, Hashable { - public static let method: String = "workspace/tests" - public typealias Response = [TestItem] - - public init() {} -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/CallHierarchyItem.swift b/Sources/LanguageServerProtocol/SupportTypes/CallHierarchyItem.swift deleted file mode 100644 index c60c81088..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/CallHierarchyItem.swift +++ /dev/null @@ -1,60 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A single call hierarchy item. -public struct CallHierarchyItem: ResponseType, Hashable { - /// Name of this item. - public var name: String - - public var kind: SymbolKind - public var tags: [SymbolTag]? - - /// More detail for this item, e.g. the signature of a function. - public var detail: String? - - /// The resource identifier of this item. - public var uri: DocumentURI - - /// The range enclosing this symbol, excluding leading/trailing whitespace - /// but including everything else, e.g. comments and code. - @CustomCodable - public var range: Range - - /// The range that should be selected and revealed when this symbol is being - /// picked, e.g. the name of a function. Must be contained by the `range`. - @CustomCodable - public var selectionRange: Range - - /// A data entry field that is preserved between a call hierarchy prepare and - /// incoming calls or outgoing calls requests. - public var data: LSPAny? - - public init( - name: String, - kind: SymbolKind, - tags: [SymbolTag]?, - detail: String? = nil, - uri: DocumentURI, - range: Range, - selectionRange: Range, - data: LSPAny? = nil - ) { - self.name = name - self.kind = kind - self.tags = tags - self.detail = detail - self.uri = uri - self.range = range - self.selectionRange = selectionRange - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/ClientCapabilities.swift b/Sources/LanguageServerProtocol/SupportTypes/ClientCapabilities.swift deleted file mode 100644 index 231b6057b..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/ClientCapabilities.swift +++ /dev/null @@ -1,1040 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Capabilities provided by the client editor/IDE. -public struct ClientCapabilities: Hashable, Codable, Sendable { - - /// Workspace-specific client capabilities. - public var workspace: WorkspaceClientCapabilities? - - /// Document-specific client capabilities. - public var textDocument: TextDocumentClientCapabilities? - - /// Capabilities specific to the notebook document support. - public var notebookDocument: NotebookDocumentClientCapabilities? - - /// Window specific client capabilities. - public var window: WindowClientCapabilities? - - /// General client capabilities. - public var general: GeneralClientCapabilities? - - /// Experimental client capabilities. - public var experimental: LSPAny? - - public init( - workspace: WorkspaceClientCapabilities? = nil, - textDocument: TextDocumentClientCapabilities? = nil, - notebookDocument: NotebookDocumentClientCapabilities? = nil, - window: WindowClientCapabilities? = nil, - general: GeneralClientCapabilities? = nil, - experimental: LSPAny? = nil - ) { - self.workspace = workspace - self.textDocument = textDocument - self.notebookDocument = notebookDocument - self.window = window - self.general = general - self.experimental = experimental - } -} - -/// Helper capability wrapper for structs that only have a `dynamicRegistration` member. -public struct DynamicRegistrationCapability: Hashable, Codable, Sendable { - /// Whether the client supports dynamic registration of this feature. - public var dynamicRegistration: Bool? = nil - - public init(dynamicRegistration: Bool? = nil) { - self.dynamicRegistration = dynamicRegistration - } -} - -/// Helper capability wrapper for structs that only have a `refreshSupport` member. -public struct RefreshRegistrationCapability: Hashable, Codable, Sendable { - /// Whether the client implementation supports a refresh request sent from the - /// server to the client. - public var refreshSupport: Bool? - - public init(refreshSupport: Bool? = nil) { - self.refreshSupport = refreshSupport - } -} - -/// Capabilities of the client editor/IDE related to managing the workspace. -public struct WorkspaceClientCapabilities: Hashable, Codable, Sendable { - - /// Capabilities specific to `WorkspaceEdit`. - public struct WorkspaceEdit: Hashable, Codable, Sendable { - /// Whether the client supports the `documentChanges` field of `WorkspaceEdit`. - public var documentChanges: Bool? = nil - - public init(documentChanges: Bool? = nil) { - self.documentChanges = documentChanges - } - } - - /// Capabilities specific to the `workspace/symbol` request. - public struct Symbol: Hashable, Codable, Sendable { - - /// Capabilities specific to `SymbolKind`. - public struct SymbolKindValueSet: Hashable, Codable, Sendable { - - /// The symbol kind values that the client can support. - /// - /// If not specified, the client support only the kinds from `File` to `Array` from LSP 1. - /// - /// If specified, the client *also* guarantees that it will handle unknown kinds gracefully. - public var valueSet: [SymbolKind]? = nil - - public init(valueSet: [SymbolKind]? = nil) { - self.valueSet = valueSet - } - } - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - public var symbolKind: SymbolKindValueSet? = nil - - public init(dynamicRegistration: Bool? = nil, symbolKind: SymbolKindValueSet? = nil) { - self.dynamicRegistration = dynamicRegistration - self.symbolKind = symbolKind - } - } - - public struct FileOperations: Hashable, Codable, Sendable { - /// Whether the client supports dynamic registration for file - /// requests/notifications. - public var dynamicRegistration: Bool? - - /// The client has support for sending didCreateFiles notifications. - public var didCreate: Bool? - - /// The client has support for sending willCreateFiles requests. - public var willCreate: Bool? - - /// The client has support for sending didRenameFiles notifications. - public var didRename: Bool? - - /// The client has support for sending willRenameFiles requests. - public var willRename: Bool? - - /// The client has support for sending didDeleteFiles notifications. - public var didDelete: Bool? - - /// The client has support for sending willDeleteFiles requests. - public var willDelete: Bool? - - public init( - dynamicRegistration: Bool? = nil, - didCreate: Bool? = nil, - willCreate: Bool? = nil, - didRename: Bool? = nil, - willRename: Bool? = nil, - didDelete: Bool? = nil, - willDelete: Bool? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.didCreate = didCreate - self.willCreate = willCreate - self.didRename = didRename - self.willRename = willRename - self.didDelete = didDelete - self.willDelete = willDelete - } - } - - // MARK: Properties - - /// Whether the client can apply text edits via the `workspace/applyEdit` request. - public var applyEdit: Bool? = nil - - public var workspaceEdit: WorkspaceEdit? = nil - - public var didChangeConfiguration: DynamicRegistrationCapability? = nil - - /// Whether the clients supports file watching - note that the protocol currently doesn't - /// support static registration for file changes. - public var didChangeWatchedFiles: DynamicRegistrationCapability? = nil - - public var symbol: Symbol? = nil - - public var executeCommand: DynamicRegistrationCapability? = nil - - /// Whether the client supports workspace folders. - public var workspaceFolders: Bool? = nil - - /// Whether the client supports the `workspace/configuration` request. - public var configuration: Bool? = nil - - public var semanticTokens: RefreshRegistrationCapability? = nil - - public var codeLens: RefreshRegistrationCapability? = nil - - public var fileOperations: FileOperations? = nil - - public var inlineValue: RefreshRegistrationCapability? = nil - - public var inlayHint: RefreshRegistrationCapability? = nil - - public var diagnostics: RefreshRegistrationCapability? = nil - - public init( - applyEdit: Bool? = nil, - workspaceEdit: WorkspaceEdit? = nil, - didChangeConfiguration: DynamicRegistrationCapability? = nil, - didChangeWatchedFiles: DynamicRegistrationCapability? = nil, - symbol: Symbol? = nil, - executeCommand: DynamicRegistrationCapability? = nil, - workspaceFolders: Bool? = nil, - configuration: Bool? = nil, - semanticTokens: RefreshRegistrationCapability? = nil, - codeLens: RefreshRegistrationCapability? = nil, - fileOperations: FileOperations? = nil, - inlineValue: RefreshRegistrationCapability? = nil, - inlayHint: RefreshRegistrationCapability? = nil, - diagnostics: RefreshRegistrationCapability? = nil - ) { - self.applyEdit = applyEdit - self.workspaceEdit = workspaceEdit - self.didChangeConfiguration = didChangeConfiguration - self.didChangeWatchedFiles = didChangeWatchedFiles - self.symbol = symbol - self.executeCommand = executeCommand - self.workspaceFolders = workspaceFolders - self.configuration = configuration - self.semanticTokens = semanticTokens - self.codeLens = codeLens - self.fileOperations = fileOperations - self.inlineValue = inlineValue - self.inlayHint = inlayHint - self.diagnostics = diagnostics - } -} - -/// Capabilities of the client editor/IDE related to the document. -public struct TextDocumentClientCapabilities: Hashable, Codable, Sendable { - - /// Capabilities specific to the `textDocument/...` change notifications. - public struct Synchronization: Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of these notifications. - public var dynamicRegistration: Bool? = nil - - /// Whether the client supports the will-save notification. - public var willSave: Bool? = nil - - /// Whether the client supports sending a will-save *request* and applies the edits from the response before saving. - public var willSaveWaitUntil: Bool? = nil - - /// Whether the client supports the did-save notification. - public var didSave: Bool? = nil - - public init( - dynamicRegistration: Bool? = nil, - willSave: Bool? = nil, - willSaveWaitUntil: Bool? = nil, - didSave: Bool? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.willSave = willSave - self.willSaveWaitUntil = willSaveWaitUntil - self.didSave = didSave - } - } - - /// Capabilities specific to the `textDocument/...` change notifications. - public struct Completion: Hashable, Codable, Sendable { - /// Capabilities specific to `CompletionItem`. - public struct CompletionItem: Hashable, Codable, Sendable { - public struct TagSupportValueSet: Hashable, Codable, Sendable { - /// The tags supported by the client. - public var valueSet: [CompletionItemTag] - - public init(valueSet: [CompletionItemTag]) { - self.valueSet = valueSet - } - } - - public struct ResolveSupportProperties: Hashable, Codable, Sendable { - /// The properties that a client can resolve lazily. - public var properties: [String] - - public init(properties: [String]) { - self.properties = properties - } - } - - public struct InsertTextModeSupportValueSet: Hashable, Codable, Sendable { - public var valueSet: [InsertTextMode] - - public init(valueSet: [InsertTextMode]) { - self.valueSet = valueSet - } - } - - /// Whether the client supports rich snippets using placeholders, etc. - public var snippetSupport: Bool? = nil - - /// Whether the client supports commit characters on a CompletionItem. - public var commitCharactersSupport: Bool? = nil - - /// Documentation formats supported by the client from most to least preferred. - public var documentationFormat: [MarkupKind]? = nil - - /// Whether the client supports the `deprecated` property on a CompletionItem. - public var deprecatedSupport: Bool? = nil - - /// Whether the client supports the `preselect` property on a CompletionItem. - public var preselectSupport: Bool? = nil - - /// Client supports the tag property on a completion item. Clients supporting tags have to handle unknown tags - /// gracefully. Clients especially need to preserve unknown tags when sending a completion item back to the server - /// in a resolve call. - public var tagSupport: TagSupportValueSet? - - /// Client supports insert replace edit to control different behavior if a completion item is inserted in the text - /// or should replace text. - public var insertReplaceSupport: Bool? - - /// Indicates which properties a client can resolve lazily on a completion item. Before version 3.16.0 only the - /// predefined properties `documentation` and `detail` could be resolved lazily. - public var resolveSupport: ResolveSupportProperties? - - /// The client supports the `insertTextMode` property on a completion item to override the whitespace handling mode - /// as defined by the client (see `insertTextMode`). - public var insertTextModeSupport: InsertTextModeSupportValueSet? - - /// The client has support for completion item label details (see also `CompletionItemLabelDetails`). - public var labelDetailsSupport: Bool? - - public init( - snippetSupport: Bool? = nil, - commitCharactersSupport: Bool? = nil, - documentationFormat: [MarkupKind]? = nil, - deprecatedSupport: Bool? = nil, - preselectSupport: Bool? = nil, - tagSupport: TagSupportValueSet? = nil, - insertReplaceSupport: Bool? = nil, - resolveSupport: ResolveSupportProperties? = nil, - insertTextModeSupport: InsertTextModeSupportValueSet? = nil, - labelDetailsSupport: Bool? = nil - ) { - self.snippetSupport = snippetSupport - self.commitCharactersSupport = commitCharactersSupport - self.documentationFormat = documentationFormat - self.deprecatedSupport = deprecatedSupport - self.preselectSupport = preselectSupport - self.tagSupport = tagSupport - self.insertReplaceSupport = insertReplaceSupport - self.resolveSupport = resolveSupport - self.insertTextModeSupport = insertTextModeSupport - self.labelDetailsSupport = labelDetailsSupport - } - } - - /// Capabilities specific to `CompletionItemKind`. - public struct CompletionItemKindValueSet: Hashable, Codable, Sendable { - - /// The completion kind values that the client can support. - /// - /// If not specified, the client support only the kinds from `Text` to `Reference` from LSP 1. - /// - /// If specified, the client *also* guarantees that it will handle unknown kinds gracefully. - public var valueSet: [CompletionItemKind]? = nil - - public init(valueSet: [CompletionItemKind]? = nil) { - self.valueSet = valueSet - } - } - - // MARK: Properties - - /// Whether the client supports dynamic registration of these capabilities. - public var dynamicRegistration: Bool? = nil - - public var completionItem: CompletionItem? = nil - - public var completionItemKind: CompletionItemKindValueSet? = nil - - /// Whether the client supports sending context information in a `textDocument/completion` request. - public var contextSupport: Bool? = nil - - public init( - dynamicRegistration: Bool? = nil, - completionItem: CompletionItem? = nil, - completionItemKind: CompletionItemKindValueSet? = nil, - contextSupport: Bool? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.completionItem = completionItem - self.completionItemKind = completionItemKind - self.contextSupport = contextSupport - } - } - - /// Capabilities specific to the `textDocument/hover` request. - public struct Hover: Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - /// Formats supported by the client for the `Hover.content` property from most to least preferred. - public var contentFormat: [MarkupKind]? = nil - - public init(dynamicRegistration: Bool? = nil, contentFormat: [MarkupKind]? = nil) { - self.dynamicRegistration = dynamicRegistration - self.contentFormat = contentFormat - } - } - - /// Capabilities specific to the `textDocument/signatureHelp` request. - public struct SignatureHelp: Hashable, Codable, Sendable { - - /// Capabilities specific to `SignatureInformation`. - public struct SignatureInformation: Hashable, Codable, Sendable { - public struct ParameterInformation: Hashable, Codable, Sendable { - /// The client supports processing label offsets instead of a simple label string. - var labelOffsetSupport: Bool? = nil - - public init(labelOffsetSupport: Bool? = nil) { - self.labelOffsetSupport = labelOffsetSupport - } - } - - /// Documentation formats supported by the client from most to least preferred. - public var documentationFormat: [MarkupKind]? = nil - - public var parameterInformation: ParameterInformation? = nil - - public init(signatureInformation: [MarkupKind]? = nil, parameterInformation: ParameterInformation? = nil) { - self.documentationFormat = signatureInformation - self.parameterInformation = parameterInformation - } - } - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - public var signatureInformation: SignatureInformation? = nil - - public init(dynamicRegistration: Bool? = nil, signatureInformation: SignatureInformation? = nil) { - self.dynamicRegistration = dynamicRegistration - self.signatureInformation = signatureInformation - } - } - - /// Capabilities specific to the `textDocument/documentSymbol` request. - public struct DocumentSymbol: Hashable, Codable, Sendable { - - /// Capabilities specific to `SymbolKind`. - public struct SymbolKindValueSet: Hashable, Codable, Sendable { - - /// The symbol kind values that the client can support. - /// - /// If not specified, the client support only the kinds from `File` to `Array` from LSP 1. - /// - /// If specified, the client *also* guarantees that it will handle unknown kinds gracefully. - public var valueSet: [SymbolKind]? = nil - - public init(valueSet: [SymbolKind]? = nil) { - self.valueSet = valueSet - } - } - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - public var symbolKind: SymbolKindValueSet? = nil - - public var hierarchicalDocumentSymbolSupport: Bool? = nil - - public init( - dynamicRegistration: Bool? = nil, - symbolKind: SymbolKindValueSet? = nil, - hierarchicalDocumentSymbolSupport: Bool? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.symbolKind = symbolKind - self.hierarchicalDocumentSymbolSupport = hierarchicalDocumentSymbolSupport - } - } - - public struct DynamicRegistrationLinkSupportCapability: Hashable, Codable, Sendable { - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - /// The client supports additional metadata in the form of declaration links. - public var linkSupport: Bool? = nil - - public init(dynamicRegistration: Bool? = nil, linkSupport: Bool? = nil) { - self.dynamicRegistration = dynamicRegistration - self.linkSupport = linkSupport - } - } - - /// Capabilities specific to the `textDocument/codeAction` request. - public struct CodeAction: Hashable, Codable, Sendable { - - /// Literals accepted by the client in response to a `textDocument/codeAction` request. - public struct CodeActionLiteralSupport: Hashable, Codable, Sendable { - /// Accepted code action kinds. - public struct CodeActionKindValueSet: Hashable, Codable, Sendable { - - /// The code action kind values that the client can support. - /// - /// If specified, the client *also* guarantees that it will handle unknown kinds gracefully. - public var valueSet: [CodeActionKind] - - public init(valueSet: [CodeActionKind]) { - self.valueSet = valueSet - } - } - - public var codeActionKind: CodeActionKindValueSet - - public init(codeActionKind: CodeActionKindValueSet) { - self.codeActionKind = codeActionKind - } - } - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? - - public var codeActionLiteralSupport: CodeActionLiteralSupport? = nil - - public init(dynamicRegistration: Bool? = nil, codeActionLiteralSupport: CodeActionLiteralSupport? = nil) { - self.codeActionLiteralSupport = codeActionLiteralSupport - } - } - - public struct CodeLens: Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? - - /// Dictionary of supported commands announced by the client. - /// The key is the CodeLens name recognized by SourceKit-LSP and the - /// value is the command as recognized by the client. - public var supportedCommands: [SupportedCodeLensCommand: String]? - - public init( - dynamicRegistration: Bool? = nil, - supportedCommands: [SupportedCodeLensCommand: String] = [:] - ) { - self.dynamicRegistration = dynamicRegistration - self.supportedCommands = supportedCommands - } - } - - /// Capabilities specific to `textDocument/rename`. - public struct Rename: Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? - - /// The client supports testing for validity of rename operations before execution. - public var prepareSupport: Bool? - - public init(dynamicRegistration: Bool? = nil, prepareSupport: Bool? = nil) { - self.dynamicRegistration = dynamicRegistration - self.prepareSupport = prepareSupport - } - } - - /// Capabilities specific to `textDocument/publishDiagnostics`. - public struct PublishDiagnostics: Hashable, Codable, Sendable { - /// Whether the client accepts diagnostics with related information. - public var relatedInformation: Bool? = nil - - /// Requests that SourceKit-LSP send `Diagnostic.codeActions`. - /// **LSP Extension from clangd**. - public var codeActionsInline: Bool? = nil - - /// Whether the client supports a `codeDescription` property. - public var codeDescriptionSupport: Bool? = nil - - public init( - relatedInformation: Bool? = nil, - codeActionsInline: Bool? = nil, - codeDescriptionSupport: Bool? = nil - ) { - self.relatedInformation = relatedInformation - self.codeActionsInline = codeActionsInline - self.codeDescriptionSupport = codeDescriptionSupport - } - } - - /// Capabilities specific to `textDocument/foldingRange`. - public struct FoldingRange: Equatable, Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - /// The maximum number of folding ranges that the client prefers to receive per document. - public var rangeLimit: Int? = nil - - /// If set, the client signals that it only supports folding complete lines. If set, client will - /// ignore specified `startUTF16Index` and `endUTF16Index` properties in a FoldingRange. - public var lineFoldingOnly: Bool? = nil - - public init(dynamicRegistration: Bool? = nil, rangeLimit: Int? = nil, lineFoldingOnly: Bool? = nil) { - self.dynamicRegistration = dynamicRegistration - self.rangeLimit = rangeLimit - self.lineFoldingOnly = lineFoldingOnly - } - } - - public struct SemanticTokensRangeClientCapabilities: Equatable, Hashable, Codable, Sendable { - // Empty in the LSP 3.16 spec. - public init() {} - } - - public struct SemanticTokensFullClientCapabilities: Equatable, Hashable, Codable, Sendable { - /// The client will also send the `textDocument/semanticTokens/full/delta` - /// request if the server provides a corresponding handler. - public var delta: Bool? - - public init(delta: Bool? = nil) { - self.delta = delta - } - } - - public struct SemanticTokensRequestsClientCapabilities: Equatable, Hashable, Codable, Sendable { - /// The client will send the `textDocument/semanticTokens/range` request - /// if the server provides a corresponding handler. - public var range: ValueOrBool? - - /// The client will send the `textDocument/semanticTokens/full` request - /// if the server provides a corresponding handler. - public var full: ValueOrBool? - - public init( - range: ValueOrBool?, - full: ValueOrBool? - ) { - self.range = range - self.full = full - } - } - - /// Capabilities specific to `textDocument/semanticTokens`. - public struct SemanticTokens: Equatable, Hashable, Codable, Sendable { - - /// Whether the client supports dynamic registration of this request. - public var dynamicRegistration: Bool? = nil - - public var requests: SemanticTokensRequestsClientCapabilities - - /// The token types that the client supports. - public var tokenTypes: [String] - - /// The token modifiers that the client supports. - public var tokenModifiers: [String] - - /// The formats the clients supports. - public var formats: [TokenFormat] - - /// Whether the client supports tokens that can overlap each other. - public var overlappingTokenSupport: Bool? = nil - - /// Whether the client supports tokens that can span multiple lines. - public var multilineTokenSupport: Bool? = nil - - public init( - dynamicRegistration: Bool? = nil, - requests: SemanticTokensRequestsClientCapabilities, - tokenTypes: [String], - tokenModifiers: [String], - formats: [TokenFormat], - overlappingTokenSupport: Bool? = nil, - multilineTokenSupport: Bool? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.requests = requests - self.tokenTypes = tokenTypes - self.tokenModifiers = tokenModifiers - self.formats = formats - self.overlappingTokenSupport = overlappingTokenSupport - self.multilineTokenSupport = multilineTokenSupport - } - } - - /// Capabilities specific to 'textDocument/inlayHint'. - public struct InlayHint: Hashable, Codable, Sendable { - /// Properties a client can resolve lazily. - public struct ResolveSupport: Hashable, Codable, Sendable { - /// The properties that a client can resolve lazily. - public var properties: [String] - - public init(properties: [String] = []) { - self.properties = properties - } - } - - /// Whether inlay hints support dynamic registration. - public var dynamicRegistration: Bool? - - /// Indicates which properties a client can resolve lazily on an inlay hint. - public var resolveSupport: ResolveSupport? - - public init( - dynamicRegistration: Bool? = nil, - resolveSupport: ResolveSupport? = nil - ) { - self.dynamicRegistration = dynamicRegistration - self.resolveSupport = resolveSupport - } - } - - /// Capabilities specific to 'textDocument/diagnostic'. Since LSP 3.17.0. - public struct Diagnostic: Equatable, Hashable, Codable, Sendable { - - /// Whether implementation supports dynamic registration. - public var dynamicRegistration: Bool? - - /// Whether the clients supports related documents for document diagnostic pulls. - public var relatedDocumentSupport: Bool? - - public init(dynamicRegistration: Bool? = nil, relatedDocumentSupport: Bool? = nil) { - self.dynamicRegistration = dynamicRegistration - self.relatedDocumentSupport = relatedDocumentSupport - } - } - - // MARK: Properties - - public var synchronization: Synchronization? = nil - - public var completion: Completion? = nil - - public var hover: Hover? = nil - - public var signatureHelp: SignatureHelp? = nil - - public var declaration: DynamicRegistrationLinkSupportCapability? = nil - - public var definition: DynamicRegistrationLinkSupportCapability? = nil - - public var typeDefinition: DynamicRegistrationLinkSupportCapability? = nil - - public var implementation: DynamicRegistrationLinkSupportCapability? = nil - - public var references: DynamicRegistrationCapability? = nil - - public var documentHighlight: DynamicRegistrationCapability? = nil - - public var documentSymbol: DocumentSymbol? = nil - - public var codeAction: CodeAction? = nil - - public var codeLens: CodeLens? = nil - - public var documentLink: DynamicRegistrationCapability? = nil - - public var colorProvider: DynamicRegistrationCapability? = nil - - public var formatting: DynamicRegistrationCapability? = nil - - public var rangeFormatting: DynamicRegistrationCapability? = nil - - public var onTypeFormatting: DynamicRegistrationCapability? = nil - - public var rename: DynamicRegistrationCapability? = nil - - public var publishDiagnostics: PublishDiagnostics? = nil - - public var foldingRange: FoldingRange? = nil - - public var selectionRange: DynamicRegistrationCapability? = nil - - public var linkedEditingRange: DynamicRegistrationCapability? = nil - - public var callHierarchy: DynamicRegistrationCapability? = nil - - public var semanticTokens: SemanticTokens? = nil - - public var moniker: DynamicRegistrationCapability? = nil - - public var typeHierarchy: DynamicRegistrationCapability? = nil - - public var inlineValue: DynamicRegistrationCapability? = nil - - public var inlayHint: InlayHint? = nil - - public var diagnostic: Diagnostic? = nil - - public init( - synchronization: Synchronization? = nil, - completion: Completion? = nil, - hover: Hover? = nil, - signatureHelp: SignatureHelp? = nil, - declaration: DynamicRegistrationLinkSupportCapability? = nil, - definition: DynamicRegistrationLinkSupportCapability? = nil, - typeDefinition: DynamicRegistrationLinkSupportCapability? = nil, - implementation: DynamicRegistrationLinkSupportCapability? = nil, - references: DynamicRegistrationCapability? = nil, - documentHighlight: DynamicRegistrationCapability? = nil, - documentSymbol: DocumentSymbol? = nil, - codeAction: CodeAction? = nil, - codeLens: CodeLens? = nil, - documentLink: DynamicRegistrationCapability? = nil, - colorProvider: DynamicRegistrationCapability? = nil, - formatting: DynamicRegistrationCapability? = nil, - rangeFormatting: DynamicRegistrationCapability? = nil, - onTypeFormatting: DynamicRegistrationCapability? = nil, - rename: DynamicRegistrationCapability? = nil, - publishDiagnostics: PublishDiagnostics? = nil, - foldingRange: FoldingRange? = nil, - selectionRange: DynamicRegistrationCapability? = nil, - linkedEditingRange: DynamicRegistrationCapability? = nil, - callHierarchy: DynamicRegistrationCapability? = nil, - semanticTokens: SemanticTokens? = nil, - moniker: DynamicRegistrationCapability? = nil, - typeHierarchy: DynamicRegistrationCapability? = nil, - inlineValue: DynamicRegistrationCapability? = nil, - inlayHint: InlayHint? = nil, - diagnostic: Diagnostic? = nil - ) { - self.synchronization = synchronization - self.completion = completion - self.hover = hover - self.signatureHelp = signatureHelp - self.declaration = declaration - self.definition = definition - self.typeDefinition = typeDefinition - self.implementation = implementation - self.references = references - self.documentHighlight = documentHighlight - self.documentSymbol = documentSymbol - self.codeAction = codeAction - self.codeLens = codeLens - self.documentLink = documentLink - self.colorProvider = colorProvider - self.formatting = formatting - self.rangeFormatting = rangeFormatting - self.onTypeFormatting = onTypeFormatting - self.rename = rename - self.publishDiagnostics = publishDiagnostics - self.foldingRange = foldingRange - self.selectionRange = selectionRange - self.linkedEditingRange = linkedEditingRange - self.callHierarchy = callHierarchy - self.semanticTokens = semanticTokens - self.moniker = moniker - self.typeHierarchy = typeHierarchy - self.inlineValue = inlineValue - self.inlayHint = inlayHint - self.diagnostic = diagnostic - } -} - -/// Capabilities specific to the notebook document support. -public struct NotebookDocumentClientCapabilities: Hashable, Codable, Sendable { - public struct NotebookDocumentSync: Hashable, Codable, Sendable { - /// Whether implementation supports dynamic registration. If this is - /// set to `true` the client supports the new - /// `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - /// return value for the corresponding server capability as well. - public var dynamicRegistration: Bool? - - /// The client supports sending execution summary data per cell. - public var executionSummarySupport: Bool? - - public init( - dynamicRegistration: Bool?, - executionSummarySupport: Bool? - ) { - self.dynamicRegistration = dynamicRegistration - self.executionSummarySupport = executionSummarySupport - } - } - - /// Capabilities specific to notebook document synchronization - public var synchronization: NotebookDocumentSync - - public init(synchronization: NotebookDocumentSync) { - self.synchronization = synchronization - } -} - -/// Window specific client capabilities. -public struct WindowClientCapabilities: Hashable, Codable, Sendable { - /// Show message request client capabilities - public struct ShowMessageRequest: Hashable, Codable, Sendable { - public struct MessageActionItem: Hashable, Codable, Sendable { - /// Whether the client supports additional attributes which - /// are preserved and sent back to the server in the - /// request's response. - public var additionalPropertiesSupport: Bool? - - public init(additionalPropertiesSupport: Bool? = nil) { - self.additionalPropertiesSupport = additionalPropertiesSupport - } - } - - /// Capabilities specific to the `MessageActionItem` type. - public var messageActionItem: MessageActionItem? - - public init(messageActionItem: MessageActionItem? = nil) { - self.messageActionItem = messageActionItem - } - } - - /// Client capabilities for the show document request. - public struct ShowDocument: Hashable, Codable, Sendable { - /// The client has support for the show document - /// request. - public var support: Bool - - public init(support: Bool) { - self.support = support - } - } - - /// It indicates whether the client supports server initiated - /// progress using the `window/workDoneProgress/create` request. - /// - /// The capability also controls Whether client supports handling - /// of progress notifications. If set servers are allowed to report a - /// `workDoneProgress` property in the request specific server - /// capabilities. - public var workDoneProgress: Bool? - - /// Capabilities specific to the showMessage request - public var showMessage: ShowMessageRequest? - - public var showDocument: ShowDocument? - - public init( - workDoneProgress: Bool? = nil, - showMessage: ShowMessageRequest? = nil, - showDocument: ShowDocument? = nil - ) { - self.workDoneProgress = workDoneProgress - self.showMessage = showMessage - self.showDocument = showDocument - } -} - -/// General client capabilities. -public struct GeneralClientCapabilities: Hashable, Codable, Sendable { - public struct StaleRequestSupport: Hashable, Codable, Sendable { - /// The client will actively cancel the request. - public var cancel: Bool - - /// The list of requests for which the client - /// will retry the request if it receives a - /// response with error code `ContentModified`` - public var retryOnContentModified: [String] - - public init(cancel: Bool, retryOnContentModified: [String]) { - self.cancel = cancel - self.retryOnContentModified = retryOnContentModified - } - } - - /// Client capabilities specific to regular expressions. - public struct RegularExpressions: Hashable, Codable, Sendable { - /// The engine's name. - public var engine: String - - /// The engine's version. - public var version: String? - - public init(engine: String, version: String? = nil) { - self.engine = engine - self.version = version - } - } - - /// Client capabilities specific to the used markdown parser. - public struct Markdown: Hashable, Codable, Sendable { - /// The name of the parser. - public var parser: String - - /// The version of the parser. - public var version: String? - - /// A list of HTML tags that the client allows / supports in Markdown. - public var allowedTags: [String]? - - public init(parser: String, version: String? = nil, allowedTags: [String]? = nil) { - self.parser = parser - self.version = version - self.allowedTags = allowedTags - } - } - - /// A type indicating how positions are encoded, - /// specifically what column offsets mean. - public enum PositionEncodingKind: String, Hashable, Codable, Sendable { - - /// Character offsets count UTF-8 code units (e.g bytes). - case utf8 = "utf-8" - - /// Character offsets count UTF-16 code units. - /// - /// This is the default and must always be supported - /// by servers - case utf16 = "utf-16" - - /// Character offsets count UTF-32 code units. - /// - /// Implementation note: these are the same as Unicode code points, - /// so this `PositionEncodingKind` may also be used for an - /// encoding-agnostic representation of character offsets. - case utf32 = "utf-32" - } - - /// Client capability that signals how the client - /// handles stale requests (e.g. a request - /// for which the client will not process the response - /// anymore since the information is outdated). - public var staleRequestSupport: StaleRequestSupport? - - /// Client capabilities specific to regular expressions. - public var regularExpressions: RegularExpressions? - - /// Client capabilities specific to the client's markdown parser. - public var markdown: Markdown? - - /// The position encodings supported by the client. Client and server - /// have to agree on the same position encoding to ensure that offsets - /// (e.g. character position in a line) are interpreted the same on both - /// side. - /// - /// To keep the protocol backwards compatible the following applies: if - /// the value 'utf-16' is missing from the array of position encodings - /// servers can assume that the client supports UTF-16. UTF-16 is - /// therefore a mandatory encoding. - /// - /// If omitted it defaults to ['utf-16']. - /// - /// Implementation considerations: since the conversion from one encoding - /// into another requires the content of the file / line the conversion - /// is best done where the file is read which is usually on the server - /// side. - public var positionEncodings: [PositionEncodingKind]? - - public init( - staleRequestSupport: StaleRequestSupport? = nil, - regularExpressions: RegularExpressions? = nil, - markdown: Markdown? = nil, - positionEncodings: [PositionEncodingKind]? = nil - ) { - self.staleRequestSupport = staleRequestSupport - self.regularExpressions = regularExpressions - self.markdown = markdown - self.positionEncodings = positionEncodings - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/CodeActionKind.swift b/Sources/LanguageServerProtocol/SupportTypes/CodeActionKind.swift deleted file mode 100644 index 7131f3013..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/CodeActionKind.swift +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A code action kind. -/// -/// In LSP, this is a string, so we don't use a closed set. -public struct CodeActionKind: RawRepresentable, Codable, Hashable, Sendable { - - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// Empty kind. - public static let empty: CodeActionKind = CodeActionKind(rawValue: "") - - /// QuickFix action, such as FixIt. - public static let quickFix: CodeActionKind = CodeActionKind(rawValue: "quickfix") - - /// Base kind for refactoring action. - public static let refactor: CodeActionKind = CodeActionKind(rawValue: "refactor") - - /// Base kind for refactoring extract action, such as extract method or extract variable. - public static let refactorExtract: CodeActionKind = CodeActionKind(rawValue: "refactor.extract") - - /// Base kind for refactoring inline action, such as inline method, or inline variable. - public static let refactorInline: CodeActionKind = CodeActionKind(rawValue: "refactor.inline") - - /// Refactoring rewrite action. - public static let refactorRewrite: CodeActionKind = CodeActionKind(rawValue: "refactor.rewrite") - - /// Source action that applies to the entire file. - public static let source: CodeActionKind = CodeActionKind(rawValue: "source") - - /// Organize imports action. - public static let sourceOrganizeImports: CodeActionKind = CodeActionKind(rawValue: "source.organizeImports") - - /// Base kind for a 'fix all' source action: `source.fixAll`. - /// - /// 'Fix all' actions automatically fix errors that have a clear fix that - /// do not require user input. They should not suppress errors or perform - /// unsafe fixes such as generating new types or classes. - public static let sourceFixAll: CodeActionKind = CodeActionKind(rawValue: "source.fixAll") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/Command.swift b/Sources/LanguageServerProtocol/SupportTypes/Command.swift deleted file mode 100644 index f9373a895..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Command.swift +++ /dev/null @@ -1,32 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Represents a reference to a command identified by a string. Used as the result of -/// requests that returns actions to the user, later used as the parameter of -/// workspace/executeCommand if the user wishes to execute said command. -public struct Command: Codable, Hashable, Sendable { - - /// The title of this command. - public var title: String - - /// The internal identifier of this command. - public var command: String - - /// The arguments related to this command. - public var arguments: [LSPAny]? - - public init(title: String, command: String, arguments: [LSPAny]?) { - self.title = title - self.command = command - self.arguments = arguments - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/CompletionItem.swift b/Sources/LanguageServerProtocol/SupportTypes/CompletionItem.swift deleted file mode 100644 index 4bedc3230..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/CompletionItem.swift +++ /dev/null @@ -1,241 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Additional details for a completion item label. -public struct CompletionItemLabelDetails: Codable, Hashable, Sendable { - - /// An optional string which is rendered less prominently directly after - /// {@link CompletionItem.label label}, without any spacing. Should be - /// used for function signatures or type annotations. - public var detail: String? - - /// An optional string which is rendered less prominently after - /// `CompletionItemLabelDetails.detail`. Should be used for fully qualified - /// names or file path. - public var description: String? - - public init(detail: String? = nil, description: String? = nil) { - self.detail = detail - self.description = description - } -} - -/// Completion item tags are extra annotations that tweak the rendering of a -/// completion item. -public struct CompletionItemTag: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Render a completion as obsolete, usually using a strike-out. - public static let deprecated = CompletionItemTag(rawValue: 1) -} - -public enum CompletionItemEdit: Codable, Hashable, Sendable { - case textEdit(TextEdit) - case insertReplaceEdit(InsertReplaceEdit) - - public init(from decoder: Decoder) throws { - if let textEdit = try? TextEdit(from: decoder) { - self = .textEdit(textEdit) - } else if let insertReplaceEdit = try? InsertReplaceEdit(from: decoder) { - self = .insertReplaceEdit(insertReplaceEdit) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected TextEdit or InsertReplaceEdit" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .textEdit(let textEdit): - try textEdit.encode(to: encoder) - case .insertReplaceEdit(let insertReplaceEdit): - try insertReplaceEdit.encode(to: encoder) - } - } -} - -/// A single completion result. -public struct CompletionItem: ResponseType, Codable, Hashable, Sendable { - - /// The display name of the completion. - public var label: String - - /// Additional details for the label - public var labelDetails: CompletionItemLabelDetails? - - /// The kind of completion item - e.g. method, property. - public var kind: CompletionItemKind - - /// Tags for this completion item. - public var tags: [CompletionItemTag]? - - /// An extended human-readable name (longer than `label`, but simpler than `documentation`). - public var detail: String? - - /// A human-readable string that represents a doc-comment. - public var documentation: StringOrMarkupContent? - - /// Whether the completion is for a deprecated symbol. - public var deprecated: Bool? - - /// Select this item when showing. - /// - /// *Note* that only one completion item can be selected and that the - /// tool / client decides which item that is. The rule is that the *first* - /// item of those that match best is selected. - public var preselect: Bool? - - /// The name to use for sorting the result. If `nil`, use `label. - public var sortText: String? - - /// The name to use for filtering the result. If `nil`, use `label. - public var filterText: String? - - /// **Deprecated**: use `textEdit` - /// - /// The string to insert into the document. If `nil`, use `label. - public var insertText: String? - - /// The format of the `textEdit.nextText` or `insertText` value. - public var insertTextFormat: InsertTextFormat? - - /// How whitespace and indentation is handled during completion - /// item insertion. If not provided the client's default value depends on - /// the `textDocument.completion.insertTextMode` client capability. - public var insertTextMode: InsertTextMode? - - /// The (primary) edit to apply to the document if this completion is accepted. - /// - /// This takes precedence over `insertText`. - /// - /// - Note: The range of the edit must contain the completion position. - public var textEdit: CompletionItemEdit? - - /// The edit text used if the completion item is part of a CompletionList and - /// CompletionList defines an item default for the text edit range. - /// - /// Clients will only honor this property if they opt into completion list - /// item defaults using the capability `completionList.itemDefaults`. - /// - /// If not provided and a list's default range is provided the label - /// property is used as a text. - public var textEditText: String? - - /// An optional array of additional text edits that are applied when - /// selecting this completion. Edits must not overlap (including the same - /// insert position) with the main edit nor with themselves. - /// - /// Additional text edits should be used to change text unrelated to the - /// current cursor position (for example adding an import statement at the - /// top of the file if the completion item will insert an unqualified type). - public var additionalTextEdits: [TextEdit]? - - /// An optional set of characters that when pressed while this completion is - /// active will accept it first and then type that character. *Note* that all - /// commit characters should have `length=1` and that superfluous characters - /// will be ignored. - public var commitCharacters: [String]? - - /// An optional command that is executed *after* inserting this completion. - /// *Note* that additional modifications to the current document should be - /// described with the additionalTextEdits-property. - public var command: Command? - - /// A data entry field that is preserved on a completion item between - /// a completion and a completion resolve request. - public var data: LSPAny? - - public init( - label: String, - labelDetails: CompletionItemLabelDetails? = nil, - kind: CompletionItemKind, - tags: [CompletionItemTag]? = nil, - detail: String? = nil, - documentation: StringOrMarkupContent? = nil, - deprecated: Bool? = nil, - preselect: Bool? = nil, - sortText: String? = nil, - filterText: String? = nil, - insertText: String? = nil, - insertTextFormat: InsertTextFormat? = nil, - insertTextMode: InsertTextMode? = nil, - textEdit: CompletionItemEdit? = nil, - textEditText: String? = nil, - additionalTextEdits: [TextEdit]? = nil, - commitCharacters: [String]? = nil, - command: Command? = nil, - data: LSPAny? = nil - ) { - self.label = label - self.labelDetails = labelDetails - self.kind = kind - self.tags = tags - self.detail = detail - self.documentation = documentation - self.deprecated = deprecated - self.preselect = preselect - self.sortText = sortText - self.filterText = filterText - self.insertText = insertText - self.insertTextFormat = insertTextFormat - self.insertTextMode = insertTextMode - self.textEdit = textEdit - self.textEditText = textEditText - self.additionalTextEdits = additionalTextEdits - self.commitCharacters = commitCharacters - self.command = command - self.data = data - } -} - -/// The format of the returned insertion text - either literal plain text or a snippet. -public enum InsertTextFormat: Int, Codable, Hashable, Sendable { - - /// The text to insert is plain text. - case plain = 1 - - /// The text to insert is a "snippet", which may contain placeholders. - case snippet = 2 -} - -/// How whitespace and indentation is handled during completion -/// item insertion. -public struct InsertTextMode: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// The insertion or replace strings is taken as it is. If the - /// value is multi line the lines below the cursor will be - /// inserted using the indentation defined in the string value. - /// The client will not apply any kind of adjustments to the - /// string. - public static let asIs = InsertTextMode(rawValue: 1) - - /// The editor adjusts leading whitespace of new lines so that - /// they match the indentation up to the cursor of the line for - /// which the item is accepted. - /// - /// Consider a line like this: <2tabs><3tabs>foo. Accepting a - /// multi line completion item is indented using 2 tabs and all - /// following lines inserted will be indented using 2 tabs as well. - public static let adjustIndentation = InsertTextMode(rawValue: 2) -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/CompletionItemKind.swift b/Sources/LanguageServerProtocol/SupportTypes/CompletionItemKind.swift deleted file mode 100644 index 1fc6db2dc..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/CompletionItemKind.swift +++ /dev/null @@ -1,54 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A completion kind. -/// -/// In LSP, this is an integer, so we don't use a closed set. -public struct CompletionItemKind: RawRepresentable, Codable, Hashable, Sendable { - - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - // MARK: LSP completion kinds - - // LSP 1 kinds, guaranteed to be supported by all clients. - public static let text: CompletionItemKind = CompletionItemKind(rawValue: 1) - public static let method: CompletionItemKind = CompletionItemKind(rawValue: 2) - public static let function: CompletionItemKind = CompletionItemKind(rawValue: 3) - public static let constructor: CompletionItemKind = CompletionItemKind(rawValue: 4) - public static let field: CompletionItemKind = CompletionItemKind(rawValue: 5) - public static let variable: CompletionItemKind = CompletionItemKind(rawValue: 6) - public static let `class`: CompletionItemKind = CompletionItemKind(rawValue: 7) - public static let interface: CompletionItemKind = CompletionItemKind(rawValue: 8) - public static let module: CompletionItemKind = CompletionItemKind(rawValue: 9) - public static let property: CompletionItemKind = CompletionItemKind(rawValue: 10) - public static let unit: CompletionItemKind = CompletionItemKind(rawValue: 11) - public static let value: CompletionItemKind = CompletionItemKind(rawValue: 12) - public static let `enum`: CompletionItemKind = CompletionItemKind(rawValue: 13) - public static let keyword: CompletionItemKind = CompletionItemKind(rawValue: 14) - public static let snippet: CompletionItemKind = CompletionItemKind(rawValue: 15) - public static let color: CompletionItemKind = CompletionItemKind(rawValue: 16) - public static let file: CompletionItemKind = CompletionItemKind(rawValue: 17) - public static let reference: CompletionItemKind = CompletionItemKind(rawValue: 18) - - // LSP 3+ - public static let folder: CompletionItemKind = CompletionItemKind(rawValue: 19) - public static let enumMember: CompletionItemKind = CompletionItemKind(rawValue: 20) - public static let constant: CompletionItemKind = CompletionItemKind(rawValue: 21) - public static let `struct`: CompletionItemKind = CompletionItemKind(rawValue: 22) - public static let event: CompletionItemKind = CompletionItemKind(rawValue: 23) - public static let `operator`: CompletionItemKind = CompletionItemKind(rawValue: 24) - public static let typeParameter: CompletionItemKind = CompletionItemKind(rawValue: 25) -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/Diagnostic.swift b/Sources/LanguageServerProtocol/SupportTypes/Diagnostic.swift deleted file mode 100644 index 1cef3d57e..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Diagnostic.swift +++ /dev/null @@ -1,172 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The severity level of a Diagnostic, between hint and error. -public enum DiagnosticSeverity: Int, Codable, Hashable, Sendable { - case error = 1 - case warning = 2 - case information = 3 - case hint = 4 -} - -/// A unique diagnostic code, which may be used identifier the diagnostic in e.g. documentation. -public enum DiagnosticCode: Hashable, Sendable { - case number(Int) - case string(String) -} - -/// Captures a description of a diagnostic error code. -public struct CodeDescription: Codable, Hashable, Sendable { - - /// A URI to open with more information about the diagnostic. - public var href: DocumentURI - - public init(href: DocumentURI) { - self.href = href - } -} - -/// A diagnostic message such a compiler error or warning. -public struct Diagnostic: Codable, Hashable, Sendable { - - /// The primary position/range of the diagnostic. - @CustomCodable - public var range: Range - - /// Whether this is a warning, error, etc. - public var severity: DiagnosticSeverity? - - /// The "code" of the diagnostice, which might be a number or string, typically providing a unique - /// way to reference the diagnostic in e.g. documentation. - public var code: DiagnosticCode? - - /// An optional description of the diagnostic code. - public var codeDescription: CodeDescription? - - /// A human-readable description of the source of this diagnostic, e.g. "sourcekitd" - public var source: String? - - /// The diagnostic message. - public var message: String - - /// Additional metadata about the diagnostic. - public var tags: [DiagnosticTag]? - - /// Related diagnostic notes. - public var relatedInformation: [DiagnosticRelatedInformation]? - - /// A data entry field that is preserved between a - /// `textDocument/publishDiagnostics` notification and - /// `textDocument/codeAction` request. - public var data: LSPAny? - - /// All the code actions that address this diagnostic. - /// **LSP Extension from clangd**. - public var codeActions: [CodeAction]? - - public init( - range: Range, - severity: DiagnosticSeverity?, - code: DiagnosticCode? = nil, - codeDescription: CodeDescription? = nil, - source: String?, - message: String, - tags: [DiagnosticTag]? = nil, - relatedInformation: [DiagnosticRelatedInformation]? = nil, - data: LSPAny? = nil, - codeActions: [CodeAction]? = nil - ) { - self._range = CustomCodable(wrappedValue: range) - self.severity = severity - self.code = code - self.codeDescription = codeDescription - self.source = source - self.message = message - self.tags = tags - self.relatedInformation = relatedInformation - self.data = data - self.codeActions = codeActions - } -} - -/// A small piece of metadata about a diagnostic that lets editors e.g. style the diagnostic -/// in a special way. -public struct DiagnosticTag: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Unused or unnecessary code. - /// - /// Clients are allowed to render diagnostics with this tag faded out - /// instead of having an error squiggle. - public static let unnecessary: DiagnosticTag = DiagnosticTag(rawValue: 1) - - /// Deprecated or obsolete code. - /// - /// Clients are allowed to rendered diagnostics with this tag strike through. - public static let deprecated: DiagnosticTag = DiagnosticTag(rawValue: 2) -} - -/// A 'note' diagnostic attached to a primary diagnostic that provides additional information. -public struct DiagnosticRelatedInformation: Codable, Hashable, Sendable { - - /// The location of this related diagnostic information. - public var location: Location - - /// The message of this related diagnostic information. - public var message: String - - /// All the code actions that address the parent diagnostic via this note. - /// **LSP Extension from clangd**. - public var codeActions: [CodeAction]? - - public init(location: Location, message: String, codeActions: [CodeAction]? = nil) { - self.location = location - self.message = message - self.codeActions = codeActions - } -} - -extension DiagnosticCode: Codable { - public init(from decoder: Decoder) throws { - let value = try decoder.singleValueContainer() - if let intValue = try? value.decode(Int.self) { - self = .number(intValue) - } else if let strValue = try? value.decode(String.self) { - self = .string(strValue) - } else { - throw MessageDecodingError.invalidRequest("could not decode diagnostic code") - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .string(let value): - try container.encode(value) - case .number(let value): - try container.encode(value) - } - } -} - -extension DiagnosticCode: CustomStringConvertible { - public var description: String { - switch self { - case .number(let n): return String(n) - case .string(let s): return "\"\(s)\"" - } - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/DocumentURI.swift b/Sources/LanguageServerProtocol/SupportTypes/DocumentURI.swift deleted file mode 100644 index 3f0e470a1..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/DocumentURI.swift +++ /dev/null @@ -1,116 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation - -struct FailedToConstructDocumentURIFromStringError: Error, CustomStringConvertible { - let string: String - - var description: String { - return "Failed to construct DocumentURI from '\(string)'" - } -} - -public struct DocumentURI: Codable, Hashable, Sendable { - /// The URL that store the URIs value - private let storage: URL - - public var description: String { - return storage.description - } - - public var fileURL: URL? { - if storage.isFileURL { - return storage - } else { - return nil - } - } - - /// The URL representation of the URI. Note that this URL can have an arbitrary scheme and might - /// not represent a file URL. - public var arbitrarySchemeURL: URL { storage } - - /// The document's URL scheme, if present. - public var scheme: String? { - return storage.scheme - } - - /// Returns a filepath if the URI is a URL. If the URI is not a URL, returns - /// the full URI as a fallback. - /// This value is intended to be used when interacting with sourcekitd which - /// expects a file path but is able to handle arbitrary strings as well in a - /// fallback mode that drops semantic functionality. - public var pseudoPath: String { - if storage.isFileURL { - return storage.withUnsafeFileSystemRepresentation { filePathPtr in - guard let filePathPtr else { - return "" - } - let filePath = String(cString: filePathPtr) - #if os(Windows) - // VS Code spells file paths with a lowercase drive letter, while the rest of Windows APIs use an uppercase - // drive letter. Normalize the drive letter spelling to be uppercase. - if filePath.first?.isASCII ?? false, filePath.first?.isLetter ?? false, filePath.first?.isLowercase ?? false, - filePath.count > 1, filePath[filePath.index(filePath.startIndex, offsetBy: 1)] == ":" - { - return filePath.first!.uppercased() + filePath.dropFirst() - } - #endif - return filePath - } - } else { - return storage.absoluteString - } - } - - /// Returns the URI as a string. - public var stringValue: String { - return storage.absoluteString - } - - /// Construct a DocumentURI from the given URI string, automatically parsing - /// it either as a URL or an opaque URI. - public init(string: String) throws { - guard let url = URL(string: string) else { - throw FailedToConstructDocumentURIFromStringError(string: string) - } - self.init(url) - } - - public init(_ url: URL) { - self.storage = url - assert(self.storage.scheme != nil, "Received invalid URI without a scheme '\(self.storage.absoluteString)'") - } - - public init(filePath: String, isDirectory: Bool) { - self.init(URL(fileURLWithPath: filePath, isDirectory: isDirectory)) - } - - public init(from decoder: Decoder) throws { - try self.init(string: decoder.singleValueContainer().decode(String.self)) - } - - /// Equality check to handle escape sequences in file URLs. - public static func == (lhs: DocumentURI, rhs: DocumentURI) -> Bool { - return lhs.storage.scheme == rhs.storage.scheme && lhs.pseudoPath == rhs.pseudoPath - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(self.storage.scheme) - hasher.combine(self.pseudoPath) - } - - public func encode(to encoder: Encoder) throws { - try storage.absoluteString.encode(to: encoder) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/FileEvent.swift b/Sources/LanguageServerProtocol/SupportTypes/FileEvent.swift deleted file mode 100644 index 4b90c2956..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/FileEvent.swift +++ /dev/null @@ -1,39 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// An event describing a file change. -public struct FileEvent: Codable, Hashable, Sendable { - public var uri: DocumentURI - public var type: FileChangeType - - public init(uri: DocumentURI, type: FileChangeType) { - self.uri = uri - self.type = type - } -} -/// The type of file event. -/// -/// In LSP, this is an integer, so we don't use a closed set. -public struct FileChangeType: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// The file was created. - public static let created: FileChangeType = FileChangeType(rawValue: 1) - /// The file was changed. - public static let changed: FileChangeType = FileChangeType(rawValue: 2) - /// The file was deleted. - public static let deleted: FileChangeType = FileChangeType(rawValue: 3) -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/FileSystemWatcher.swift b/Sources/LanguageServerProtocol/SupportTypes/FileSystemWatcher.swift deleted file mode 100644 index 25e645089..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/FileSystemWatcher.swift +++ /dev/null @@ -1,68 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Defines a watcher interested in specific file system change events. -public struct FileSystemWatcher: Codable, Hashable, Sendable { - /// The glob pattern to watch. - public var globPattern: String - - /// The kind of events of interest. If omitted it defaults to - /// WatchKind.create | WatchKind.change | WatchKind.delete. - public var kind: WatchKind? - - public init(globPattern: String, kind: WatchKind? = nil) { - self.globPattern = globPattern - self.kind = kind - } -} - -extension FileSystemWatcher: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let globPatternAny = dictionary[CodingKeys.globPattern.stringValue] else { return nil } - guard case .string(let globPattern) = globPatternAny else { return nil } - self.globPattern = globPattern - - guard let kindValue = dictionary[CodingKeys.kind.stringValue] else { - self.kind = nil - return - } - - switch kindValue { - case .null: self.kind = nil - case .int(let value): self.kind = WatchKind(rawValue: value) - default: return nil - } - } - - public func encodeToLSPAny() -> LSPAny { - var encoded = [CodingKeys.globPattern.stringValue: LSPAny.string(globPattern)] - if let kind = kind { - encoded[CodingKeys.kind.stringValue] = LSPAny.int(kind.rawValue) - } - return .dictionary(encoded) - } -} - -/// The type of file event a watcher is interested in. -/// -/// In LSP, this is an integer, so we don't use a closed set. -public struct WatchKind: OptionSet, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - public static let create: WatchKind = WatchKind(rawValue: 1) - public static let change: WatchKind = WatchKind(rawValue: 2) - public static let delete: WatchKind = WatchKind(rawValue: 4) -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/FoldingRangeKind.swift b/Sources/LanguageServerProtocol/SupportTypes/FoldingRangeKind.swift deleted file mode 100644 index b377baebd..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/FoldingRangeKind.swift +++ /dev/null @@ -1,32 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A folding range kind. -/// -/// In LSP, this is a string, so we don't use a closed set. -public struct FoldingRangeKind: RawRepresentable, Codable, Hashable, Sendable { - - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// Folding range for a comment. - public static let comment: FoldingRangeKind = FoldingRangeKind(rawValue: "comment") - - /// Folding range for imports or includes. - public static let imports: FoldingRangeKind = FoldingRangeKind(rawValue: "imports") - - /// Folding range for a region (e.g. C# `#region`). - public static let region: FoldingRangeKind = FoldingRangeKind(rawValue: "region") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/InlayHint.swift b/Sources/LanguageServerProtocol/SupportTypes/InlayHint.swift deleted file mode 100644 index dedab3055..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/InlayHint.swift +++ /dev/null @@ -1,144 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Represents an inline annotation displayed by the editor in a source file. -public struct InlayHint: ResponseType, Codable, Hashable, Sendable { - /// The position within the code that this hint is attached to. - public var position: Position - - /// The hint's text, e.g. a printed type - public let label: InlayHintLabel - - /// The hint's kind, used for more flexible client-side styling. - public let kind: InlayHintKind? - - /// Optional text edits that are performed when accepting this inlay hint. - public let textEdits: [TextEdit]? - - /// The tooltip text displayed when the inlay hint is hovered. - public let tooltip: StringOrMarkupContent? - - /// Whether to render padding before the hint. - public let paddingLeft: Bool? - - /// Whether to render padding after the hint. - public let paddingRight: Bool? - - /// A data entry field that is present between a `textDocument/inlayHint` - /// and a `inlayHint/resolve` request. - public let data: LSPAny? - - public init( - position: Position, - label: InlayHintLabel, - kind: InlayHintKind? = nil, - textEdits: [TextEdit]? = nil, - tooltip: StringOrMarkupContent? = nil, - paddingLeft: Bool? = nil, - paddingRight: Bool? = nil, - data: LSPAny? = nil - ) { - self.position = position - self.label = label - self.kind = kind - self.textEdits = textEdits - self.tooltip = tooltip - self.paddingLeft = paddingLeft - self.paddingRight = paddingRight - self.data = data - } -} - -/// A hint's kind, used for more flexible client-side styling. -public struct InlayHintKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// A type annotation. - public static let type: InlayHintKind = InlayHintKind(rawValue: 1) - - /// A parameter label. - public static let parameter: InlayHintKind = InlayHintKind(rawValue: 2) -} - -/// A hint's label, either being a single string or a composition of parts. -public enum InlayHintLabel: Codable, Hashable, Sendable { - case parts([InlayHintLabelPart]) - case string(String) - - public init(from decoder: Decoder) throws { - if let parts = try? [InlayHintLabelPart](from: decoder) { - self = .parts(parts) - } else if let string = try? String(from: decoder) { - self = .string(string) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected [InlayHintLabelPart] or String" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case let .parts(parts): - try parts.encode(to: encoder) - case let .string(string): - try string.encode(to: encoder) - } - } -} - -extension InlayHintLabel: ExpressibleByStringLiteral { - public init(stringLiteral value: String) { - self = .string(value) - } -} - -extension InlayHintLabel: ExpressibleByStringInterpolation { - public init(stringInterpolation interpolation: DefaultStringInterpolation) { - self = .string(.init(stringInterpolation: interpolation)) - } -} - -/// A part of an interactive or composite inlay hint label. -public struct InlayHintLabelPart: Codable, Hashable, Sendable { - /// The value of this label part. - public let value: String - - /// The tooltip to show when the part is hovered. - public let tooltip: StringOrMarkupContent? - - /// An optional source code location representing this part. - /// Used by the editor for hover and code navigation, e.g. - /// by making the part a clickable link to the given position. - public let location: Location? - - /// An optional command for this label part. - public let command: Command? - - public init( - value: String, - tooltip: StringOrMarkupContent? = nil, - location: Location? = nil, - command: Command? = nil - ) { - self.value = value - self.tooltip = tooltip - self.location = location - self.command = command - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/InsertReplaceEdit.swift b/Sources/LanguageServerProtocol/SupportTypes/InsertReplaceEdit.swift deleted file mode 100644 index 7a286e379..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/InsertReplaceEdit.swift +++ /dev/null @@ -1,31 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A special text edit to provide an insert and a replace operation. -public struct InsertReplaceEdit: Codable, Hashable, Sendable { - /// The string to be inserted. - public var newText: String - - /// The range if the insert is requested - @CustomCodable - public var insert: Range - - /// The range if the replace is requested. - @CustomCodable - public var replace: Range - - public init(newText: String, insert: Range, replace: Range) { - self.newText = newText - self.insert = insert - self.replace = replace - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/LSPAny.swift b/Sources/LanguageServerProtocol/SupportTypes/LSPAny.swift deleted file mode 100644 index 2b16e1cf2..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/LSPAny.swift +++ /dev/null @@ -1,232 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Representation of 'any' in the Language Server Protocol, which is equivalent -/// to an arbitrary JSON value. -public enum LSPAny: Hashable, Sendable { - case null - case int(Int) - case bool(Bool) - case double(Double) - case string(String) - case array([LSPAny]) - case dictionary([String: LSPAny]) -} - -extension LSPAny: Decodable { - public init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if container.decodeNil() { - self = .null - } else if let value = try? container.decode(Int.self) { - self = .int(value) - } else if let value = try? container.decode(Bool.self) { - self = .bool(value) - } else if let value = try? container.decode(Double.self) { - self = .double(value) - } else if let value = try? container.decode(String.self) { - self = .string(value) - } else if let value = try? container.decode([LSPAny].self) { - self = .array(value) - } else if let value = try? container.decode([String: LSPAny].self) { - self = .dictionary(value) - } else { - let error = "LSPAny cannot be decoded: Unrecognized type." - throw DecodingError.dataCorruptedError(in: container, debugDescription: error) - } - } -} - -extension LSPAny: Encodable { - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .null: - try container.encodeNil() - case .int(let value): - try container.encode(value) - case .bool(let value): - try container.encode(value) - case .double(let value): - try container.encode(value) - case .string(let value): - try container.encode(value) - case .array(let value): - try container.encode(value) - case .dictionary(let value): - try container.encode(value) - } - } -} - -extension LSPAny: ResponseType {} - -extension LSPAny: ExpressibleByNilLiteral { - public init(nilLiteral _: ()) { - self = .null - } -} - -extension LSPAny: ExpressibleByIntegerLiteral { - public init(integerLiteral value: Int) { - self = .int(value) - } -} - -extension LSPAny: ExpressibleByBooleanLiteral { - public init(booleanLiteral value: Bool) { - self = .bool(value) - } -} - -extension LSPAny: ExpressibleByFloatLiteral { - public init(floatLiteral value: Double) { - self = .double(value) - } -} - -extension LSPAny: ExpressibleByStringLiteral { - public init(extendedGraphemeClusterLiteral value: String) { - self = .string(value) - } - - public init(stringLiteral value: String) { - self = .string(value) - } -} - -extension LSPAny: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: LSPAny...) { - self = .array(elements) - } -} - -extension LSPAny: ExpressibleByDictionaryLiteral { - public init(dictionaryLiteral elements: (String, LSPAny)...) { - let dict = [String: LSPAny](elements, uniquingKeysWith: { first, _ in first }) - self = .dictionary(dict) - } -} - -public protocol LSPAnyCodable { - init?(fromLSPDictionary dictionary: [String: LSPAny]) - func encodeToLSPAny() -> LSPAny -} - -extension LSPAnyCodable { - public init?(fromLSPAny lspAny: LSPAny?) { - guard case .dictionary(let dictionary) = lspAny else { - return nil - } - self.init(fromLSPDictionary: dictionary) - } -} - -extension Optional: LSPAnyCodable where Wrapped: LSPAnyCodable { - public init?(fromLSPAny value: LSPAny) { - if case .null = value { - self = .none - return - } - guard case .dictionary(let dict) = value else { - return nil - } - guard let wrapped = Wrapped.init(fromLSPDictionary: dict) else { - return nil - } - self = .some(wrapped) - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - return nil - } - - public func encodeToLSPAny() -> LSPAny { - guard let wrapped = self else { return .null } - return wrapped.encodeToLSPAny() - } -} - -extension Array: LSPAnyCodable where Element: LSPAnyCodable { - public init?(fromLSPArray array: LSPAny) { - guard case .array(let array) = array else { - return nil - } - - var result = [Element]() - for element in array { - switch element { - case .dictionary(let dict): - if let value = Element(fromLSPDictionary: dict) { - result.append(value) - } else { - return nil - } - case .array(let value): - if let value = value as? [Element] { - result.append(contentsOf: value) - } else { - return nil - } - case .string(let value): - if let value = value as? Element { - result.append(value) - } else { - return nil - } - case .int(let value): - if let value = value as? Element { - result.append(value) - } else { - return nil - } - case .double(let value): - if let value = value as? Element { - result.append(value) - } else { - return nil - } - case .bool(let value): - if let value = value as? Element { - result.append(value) - } else { - return nil - } - case .null: - // null is not expected for non-optional Element - return nil - } - } - self = result - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - return nil - } - - public func encodeToLSPAny() -> LSPAny { - return .array(map { $0.encodeToLSPAny() }) - } -} - -extension String: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - nil - } - - public func encodeToLSPAny() -> LSPAny { - .string(self) - } -} - -public typealias LSPObject = [String: LSPAny] -public typealias LSPArray = [LSPAny] diff --git a/Sources/LanguageServerProtocol/SupportTypes/Language.swift b/Sources/LanguageServerProtocol/SupportTypes/Language.swift deleted file mode 100644 index a5600c4da..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Language.swift +++ /dev/null @@ -1,165 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A source code language identifier, such as "swift", or "objective-c". -public struct Language: RawRepresentable, Codable, Equatable, Hashable, Sendable { - public typealias LanguageId = String - - public let rawValue: LanguageId - public init(rawValue: LanguageId) { - self.rawValue = rawValue - } - - /// Clang-compatible language name suitable for use with `-x `. - public var xflag: String? { - switch self { - case .swift: return "swift" - case .c: return "c" - case .cpp: return "c++" - case .objective_c: return "objective-c" - case .objective_cpp: return "objective-c++" - default: return nil - } - } - - /// Clang-compatible language name for a header file. See `xflag`. - public var xflagHeader: String? { - return xflag.map { "\($0)-header" } - } -} - -extension Language: CustomStringConvertible, CustomDebugStringConvertible { - public var debugDescription: String { - return rawValue - } - - public var description: String { - switch self { - case .abap: return "ABAP" - case .bat: return "Windows Bat" - case .bibtex: return "BibTeX" - case .clojure: return "Clojure" - case .coffeescript: return "Coffeescript" - case .c: return "C" - case .cpp: return "C++" - case .csharp: return "C#" - case .css: return "CSS" - case .diff: return "Diff" - case .dart: return "Dart" - case .dockerfile: return "Dockerfile" - case .fsharp: return "F#" - case .git_commit: return "Git (commit)" - case .git_rebase: return "Git (rebase)" - case .go: return "Go" - case .groovy: return "Groovy" - case .handlebars: return "Handlebars" - case .html: return "HTML" - case .ini: return "Ini" - case .java: return "Java" - case .javaScript: return "JavaScript" - case .javaScriptReact: return "JavaScript React" - case .json: return "JSON" - case .latex: return "LaTeX" - case .less: return "Less" - case .lua: return "Lua" - case .makefile: return "Makefile" - case .markdown: return "Markdown" - case .objective_c: return "Objective-C" - case .objective_cpp: return "Objective-C++" - case .perl: return "Perl" - case .perl6: return "Perl 6" - case .php: return "PHP" - case .powershell: return "Powershell" - case .jade: return "Pug" - case .python: return "Python" - case .r: return "R" - case .razor: return "Razor (cshtml)" - case .ruby: return "Ruby" - case .rust: return "Rust" - case .scss: return "SCSS (syntax using curly brackets)" - case .sass: return "SCSS (indented syntax)" - case .scala: return "Scala" - case .shaderLab: return "ShaderLab" - case .shellScript: return "Shell Script (Bash)" - case .sql: return "SQL" - case .swift: return "Swift" - case .tutorial: return "Tutorial" - case .typeScript: return "TypeScript" - case .typeScriptReact: return "TypeScript React" - case .tex: return "TeX" - case .vb: return "Visual Basic" - case .xml: return "XML" - case .xsl: return "XSL" - case .yaml: return "YAML" - default: return rawValue - } - } -} - -public extension Language { - static let abap = Language(rawValue: "abap") - static let bat = Language(rawValue: "bat") // Windows Bat - static let bibtex = Language(rawValue: "bibtex") - static let clojure = Language(rawValue: "clojure") - static let coffeescript = Language(rawValue: "coffeescript") - static let c = Language(rawValue: "c") - static let cpp = Language(rawValue: "cpp") // C++, not C preprocessor - static let csharp = Language(rawValue: "csharp") - static let css = Language(rawValue: "css") - static let diff = Language(rawValue: "diff") - static let dart = Language(rawValue: "dart") - static let dockerfile = Language(rawValue: "dockerfile") - static let fsharp = Language(rawValue: "fsharp") - static let git_commit = Language(rawValue: "git-commit") - static let git_rebase = Language(rawValue: "git-rebase") - static let go = Language(rawValue: "go") - static let groovy = Language(rawValue: "groovy") - static let handlebars = Language(rawValue: "handlebars") - static let html = Language(rawValue: "html") - static let ini = Language(rawValue: "ini") - static let java = Language(rawValue: "java") - static let javaScript = Language(rawValue: "javascript") - static let javaScriptReact = Language(rawValue: "javascriptreact") - static let json = Language(rawValue: "json") - static let latex = Language(rawValue: "latex") - static let less = Language(rawValue: "less") - static let lua = Language(rawValue: "lua") - static let makefile = Language(rawValue: "makefile") - static let markdown = Language(rawValue: "markdown") - static let objective_c = Language(rawValue: "objective-c") - static let objective_cpp = Language(rawValue: "objective-cpp") - static let perl = Language(rawValue: "perl") - static let perl6 = Language(rawValue: "perl6") - static let php = Language(rawValue: "php") - static let powershell = Language(rawValue: "powershell") - static let jade = Language(rawValue: "jade") - static let python = Language(rawValue: "python") - static let r = Language(rawValue: "r") - static let razor = Language(rawValue: "razor") // Razor (cshtml) - static let ruby = Language(rawValue: "ruby") - static let rust = Language(rawValue: "rust") - static let scss = Language(rawValue: "scss") // SCSS (syntax using curly brackets) - static let sass = Language(rawValue: "sass") // SCSS (indented syntax) - static let scala = Language(rawValue: "scala") - static let shaderLab = Language(rawValue: "shaderlab") - static let shellScript = Language(rawValue: "shellscript") // Shell Script (Bash) - static let sql = Language(rawValue: "sql") - static let swift = Language(rawValue: "swift") - static let tutorial = Language(rawValue: "tutorial") // LSP Extension: Swift DocC Tutorial - static let typeScript = Language(rawValue: "typescript") - static let typeScriptReact = Language(rawValue: "typescriptreact") // TypeScript React - static let tex = Language(rawValue: "tex") - static let vb = Language(rawValue: "vb") // Visual Basic - static let xml = Language(rawValue: "xml") - static let xsl = Language(rawValue: "xsl") - static let yaml = Language(rawValue: "yaml") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/Location.swift b/Sources/LanguageServerProtocol/SupportTypes/Location.swift deleted file mode 100644 index e9903ae85..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Location.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Range within a particular document. -/// -/// For a location where the document is implied, use `Position` or `Range`. -public struct Location: ResponseType, Hashable, Codable, CustomDebugStringConvertible, Comparable, Sendable { - public static func < (lhs: Location, rhs: Location) -> Bool { - if lhs.uri != rhs.uri { - return lhs.uri.stringValue < rhs.uri.stringValue - } - if lhs.range.lowerBound != rhs.range.lowerBound { - return lhs.range.lowerBound < rhs.range.lowerBound - } - return lhs.range.upperBound < rhs.range.upperBound - } - - public var uri: DocumentURI - - @CustomCodable - public var range: Range - - public init(uri: DocumentURI, range: Range) { - self.uri = uri - self._range = CustomCodable(wrappedValue: range) - } - - public var debugDescription: String { - return "\(uri):\(range.lowerBound)-\(range.upperBound)" - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/LocationLink.swift b/Sources/LanguageServerProtocol/SupportTypes/LocationLink.swift deleted file mode 100644 index 05b9e7e82..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/LocationLink.swift +++ /dev/null @@ -1,45 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct LocationLink: Codable, Hashable, Sendable { - /// Span of the origin of this link. - /// - /// Used as the underlined span for mouse interaction. Defaults to the word range at the mouse position. - @CustomCodable - public var originSelectionRange: Range? - - /// The target resource identifier of this link. - public var targetUri: DocumentURI - - /// The full target range of this link. If the target for example is a symbol then target range is the - /// range enclosing this symbol not including leading/trailing whitespace but everything else - /// like comments. This information is typically used to highlight the range in the editor. - @CustomCodable - public var targetRange: Range - - /// The range that should be selected and revealed when this link is being followed, e.g the name of a function. - /// Must be contained by the the `targetRange`. See also `DocumentSymbol#range` - @CustomCodable - public var targetSelectionRange: Range - - public init( - originSelectionRange: Range? = nil, - targetUri: DocumentURI, - targetRange: Range, - targetSelectionRange: Range - ) { - self._originSelectionRange = CustomCodable(wrappedValue: originSelectionRange) - self.targetUri = targetUri - self._targetRange = CustomCodable(wrappedValue: targetRange) - self._targetSelectionRange = CustomCodable(wrappedValue: targetSelectionRange) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/LocationsOrLocationLinksResponse.swift b/Sources/LanguageServerProtocol/SupportTypes/LocationsOrLocationLinksResponse.swift deleted file mode 100644 index 6ba402a33..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/LocationsOrLocationLinksResponse.swift +++ /dev/null @@ -1,42 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum LocationsOrLocationLinksResponse: ResponseType, Hashable, Sendable { - case locations([Location]) - case locationLinks([LocationLink]) - - public init(from decoder: Decoder) throws { - if let locations = try? [Location](from: decoder) { - self = .locations(locations) - } else if let locationLinks = try? [LocationLink](from: decoder) { - self = .locationLinks(locationLinks) - } else if let location = try? Location(from: decoder) { - // Fallback: Decode single location as array with one element - self = .locations([location]) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected [Location], [LocationLink], or Location" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .locations(let locations): - try locations.encode(to: encoder) - case .locationLinks(let locationLinks): - try locationLinks.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/MarkupContent.swift b/Sources/LanguageServerProtocol/SupportTypes/MarkupContent.swift deleted file mode 100644 index ace5cffea..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/MarkupContent.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The kind of markup (plaintext or markdown). -/// -/// In LSP, this is a string, so we don't use a closed set. -public struct MarkupKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - public init(rawValue: String) { - self.rawValue = rawValue - } - - public static let plaintext: MarkupKind = MarkupKind(rawValue: "plaintext") - public static let markdown: MarkupKind = MarkupKind(rawValue: "markdown") -} - -public struct MarkupContent: Codable, Hashable, Sendable { - - public var kind: MarkupKind - - public var value: String - - public init(kind: MarkupKind, value: String) { - self.kind = kind - self.value = value - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/NotebookCellTextDocumentFilter.swift b/Sources/LanguageServerProtocol/SupportTypes/NotebookCellTextDocumentFilter.swift deleted file mode 100644 index f1e2ae240..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/NotebookCellTextDocumentFilter.swift +++ /dev/null @@ -1,78 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A notebook document filter denotes a notebook document by different properties. -public struct NotebookDocumentFilter: Codable, Hashable, Sendable { - /// The type of the enclosing notebook. - public var notebookType: String? - - /// A Uri [scheme](#Uri.scheme), like `file` or `untitled`. - public var scheme: String? - - /// A glob pattern. - public var pattern: String? - - public init(notebookType: String? = nil, scheme: String? = nil, pattern: String? = nil) { - self.notebookType = notebookType - self.scheme = scheme - self.pattern = pattern - } -} - -/// A notebook cell text document filter denotes a cell text -/// document by different properties. -public struct NotebookCellTextDocumentFilter: Codable, Hashable, Sendable { - public enum NotebookFilter: Codable, Hashable, Sendable { - case string(String) - case notebookDocumentFilter(NotebookDocumentFilter) - - public init(from decoder: Decoder) throws { - if let string = try? String(from: decoder) { - self = .string(string) - } else if let filter = try? NotebookDocumentFilter(from: decoder) { - self = .notebookDocumentFilter(filter) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "NotebookFilter must be either a String or NotebookDocumentFilter" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .string(let string): - try string.encode(to: encoder) - case .notebookDocumentFilter(let filter): - try filter.encode(to: encoder) - } - } - } - - /// A filter that matches against the notebook - /// containing the notebook cell. If a string - /// value is provided it matches against the - /// notebook type. '*' matches every notebook. - public var notebook: NotebookFilter - - /// A language id like `python`. - /// - /// Will be matched against the language id of the - /// notebook cell document. '*' matches every language. - public var language: String? - - public init(notebook: NotebookFilter, language: String? = nil) { - self.notebook = notebook - self.language = language - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocument.swift b/Sources/LanguageServerProtocol/SupportTypes/NotebookDocument.swift deleted file mode 100644 index 54e4f65fb..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocument.swift +++ /dev/null @@ -1,102 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct NotebookDocument: Codable, Hashable, Sendable { - - /// The notebook document's URI. - public var uri: DocumentURI - - /// The type of the notebook. - public var notebookType: String - - /// The version number of this document (it will increase after each - /// change, including undo/redo). - public var version: Int - - /// Additional metadata stored with the notebook - /// document. - public var metadata: LSPObject? - - /// The cells of a notebook. - public var cells: [NotebookCell] - - public init(uri: DocumentURI, notebookType: String, version: Int, metadata: LSPObject? = nil, cells: [NotebookCell]) { - self.uri = uri - self.notebookType = notebookType - self.version = version - self.metadata = metadata - self.cells = cells - } -} - -/// A notebook cell kind. -public struct NotebookCellKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// A markup-cell is formatted source that is used for display. - public static let markup = NotebookCellKind(rawValue: 1) - - /// A code-cell is source code. - public static let code = NotebookCellKind(rawValue: 2) -} - -public struct ExecutionSummary: Codable, Hashable, Sendable { - /// A strict monotonically increasing value - /// indicating the execution order of a cell - /// inside a notebook. - public var executionOrder: Int - - /// Whether the execution was successful or - /// not if known by the client. - public var success: Bool? - - public init(executionOrder: Int, success: Bool?) { - self.executionOrder = executionOrder - self.success = success - } -} - -/// A notebook cell. -/// -/// A cell's document URI must be unique across ALL notebook -/// cells and can therefore be used to uniquely identify a -/// notebook cell or the cell's text document. -public struct NotebookCell: Codable, Hashable, Sendable { - - /// The cell's kind - public var kind: NotebookCellKind - - /// The URI of the cell's text document content. - public var document: DocumentURI - - /// Additional metadata stored with the cell. - public var metadata: LSPObject? - - /// Additional execution summary information if supported by the client. - public var executionSummary: ExecutionSummary? - - public init( - kind: NotebookCellKind, - document: DocumentURI, - metadata: LSPObject? = nil, - executionSummary: ExecutionSummary? = nil - ) { - self.kind = kind - self.document = document - self.metadata = metadata - self.executionSummary = executionSummary - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentChangeEvent.swift b/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentChangeEvent.swift deleted file mode 100644 index 7f3fe080a..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentChangeEvent.swift +++ /dev/null @@ -1,94 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A change describing how to move a `NotebookCell` -/// array from state S to S'. -public struct NotebookCellArrayChange: Codable, Hashable, Sendable { - /// The start offset of the cell that changed. - public var start: Int - - /// The deleted cells - public var deleteCount: Int - - /// The new cells, if any - public var cells: [NotebookCell]? - - public init(start: Int, deleteCount: Int, cells: [NotebookCell]? = nil) { - self.start = start - self.deleteCount = deleteCount - self.cells = cells - } -} - -/// A change event for a notebook document. -public struct NotebookDocumentChangeEvent: Codable, Hashable, Sendable { - public struct CellsStructure: Codable, Hashable, Sendable { - /// The change to the cell array. - public var array: NotebookCellArrayChange - - /// Additional opened cell text documents. - public var didOpen: [TextDocumentItem]? - - /// Additional closed cell text documents. - public var didClose: [TextDocumentIdentifier]? - - public init( - array: NotebookCellArrayChange, - didOpen: [TextDocumentItem]? = nil, - didClose: [TextDocumentIdentifier]? = nil - ) { - self.array = array - self.didOpen = didOpen - self.didClose = didClose - } - } - - public struct CellsTextContent: Codable, Hashable, Sendable { - public var document: VersionedTextDocumentIdentifier - public var changes: [TextDocumentContentChangeEvent] - - public init(document: VersionedTextDocumentIdentifier, changes: [TextDocumentContentChangeEvent]) { - self.document = document - self.changes = changes - } - } - - public struct Cells: Codable, Hashable, Sendable { - /// Changes to the cell structure to add or - /// remove cells. - public var structure: CellsStructure? - - /// Changes to notebook cells properties like its - /// kind, execution summary or metadata. - public var data: [NotebookCell]? - - /// Changes to the text content of notebook cells. - public var textContent: [CellsTextContent]? - - public init(structure: CellsStructure? = nil, data: [NotebookCell]? = nil, textContent: [CellsTextContent]? = nil) { - self.structure = structure - self.data = data - self.textContent = textContent - } - } - - /// The changed meta data if any. - public var metadata: LSPObject? - - /// Changes to cells - public var cells: Cells? - - public init(metadata: LSPObject? = nil, cells: Cells? = nil) { - self.metadata = metadata - self.cells = cells - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentIdentifier.swift b/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentIdentifier.swift deleted file mode 100644 index b2fcdc2e8..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/NotebookDocumentIdentifier.swift +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A literal to identify a notebook document in the client. -public struct NotebookDocumentIdentifier: Hashable, Codable, Sendable { - - /// The notebook document's URI. - public var uri: DocumentURI - - public init(_ uri: DocumentURI) { - self.uri = uri - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/Position.swift b/Sources/LanguageServerProtocol/SupportTypes/Position.swift deleted file mode 100644 index 74091f711..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Position.swift +++ /dev/null @@ -1,68 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Position within a text document, expressed as a zero-based line and column (utf-16 code unit offset). -public struct Position: Hashable, Codable, Sendable { - - /// Line number within a document (zero-based). - public var line: Int - - /// UTF-16 code-unit offset from the start of a line (zero-based). - public var utf16index: Int - - public init(line: Int, utf16index: Int) { - self.line = line - self.utf16index = utf16index - } -} - -extension Position { - private enum CodingKeys: String, CodingKey { - case line - case utf16index = "character" - } -} - -extension Position: Comparable { - public static func < (lhs: Position, rhs: Position) -> Bool { - return (lhs.line, lhs.utf16index) < (rhs.line, rhs.utf16index) - } -} - -extension Position: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard case .int(let line) = dictionary[CodingKeys.line.stringValue], - case .int(let utf16index) = dictionary[CodingKeys.utf16index.stringValue] - else { - return nil - } - self.line = line - self.utf16index = utf16index - } - - public func encodeToLSPAny() -> LSPAny { - return .dictionary([ - CodingKeys.line.stringValue: .int(line), - CodingKeys.utf16index.stringValue: .int(utf16index), - ]) - } -} - -extension Position: CustomStringConvertible, CustomDebugStringConvertible { - public var description: String { - "\(line + 1):\(utf16index+1)" - } - - public var debugDescription: String { - "Position(line: \(line), utf16index: \(utf16index))" - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/PositionEncoding.swift b/Sources/LanguageServerProtocol/SupportTypes/PositionEncoding.swift deleted file mode 100644 index c8c1323ec..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/PositionEncoding.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A set of predefined position encoding kinds. -public struct PositionEncodingKind: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// Character offsets count UTF-8 code units. - public static let utf8: PositionEncodingKind = PositionEncodingKind(rawValue: "utf-8") - - /// Character offsets count UTF-16 code units. - /// - /// This is the default and must always be supported - /// by servers - public static let utf16: PositionEncodingKind = PositionEncodingKind(rawValue: "utf-16") - - /// Character offsets count UTF-32 code units. - /// - /// Implementation note: these are the same as Unicode code points, - /// so this `PositionEncodingKind` may also be used for an - /// encoding-agnostic representation of character offsets. - public static let utf32: PositionEncodingKind = PositionEncodingKind(rawValue: "utf-32") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/ProgressToken.swift b/Sources/LanguageServerProtocol/SupportTypes/ProgressToken.swift deleted file mode 100644 index 189a3c3ba..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/ProgressToken.swift +++ /dev/null @@ -1,36 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum ProgressToken: Codable, Hashable, Sendable { - case integer(Int) - case string(String) - - public init(from decoder: Decoder) throws { - if let integer = try? Int(from: decoder) { - self = .integer(integer) - } else if let string = try? String(from: decoder) { - self = .string(string) - } else { - let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected Int or String") - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .integer(let integer): - try integer.encode(to: encoder) - case .string(let string): - try string.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/RegistrationOptions.swift b/Sources/LanguageServerProtocol/SupportTypes/RegistrationOptions.swift deleted file mode 100644 index 3beb8fcb9..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/RegistrationOptions.swift +++ /dev/null @@ -1,373 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// Protocol for capability registration options, which must be encodable to -/// `LSPAny` so they can be included in a `Registration`. -public protocol RegistrationOptions: Hashable, LSPAnyCodable { - -} - -/// General text document registration options. -public struct TextDocumentRegistrationOptions: RegistrationOptions, Hashable { - /// A document selector to identify the scope of the registration. If not set, - /// the document selector provided on the client side will be used. - public var documentSelector: DocumentSelector? - - public init(documentSelector: DocumentSelector? = nil) { - self.documentSelector = documentSelector - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if let value = dictionary["documentSelector"] { - self.documentSelector = DocumentSelector(fromLSPArray: value) - } else { - self.documentSelector = nil - } - } - - public func encodeToLSPAny() -> LSPAny { - guard let documentSelector = documentSelector else { - return .dictionary([:]) - } - - return .dictionary(["documentSelector": documentSelector.encodeToLSPAny()]) - } -} - -/// Protocol for a type which structurally represents`TextDocumentRegistrationOptions`. -public protocol TextDocumentRegistrationOptionsProtocol { - var textDocumentRegistrationOptions: TextDocumentRegistrationOptions { get } -} - -/// Code completiion registration options. -public struct CompletionRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var completionOptions: CompletionOptions - - public init(documentSelector: DocumentSelector? = nil, completionOptions: CompletionOptions) { - self.textDocumentRegistrationOptions = - TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.completionOptions = completionOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let completionOptions = CompletionOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.completionOptions = completionOptions - - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if case .dictionary(let dictionary) = completionOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - return .dictionary(dict) - } -} - -/// Signature help registration options. -public struct SignatureHelpRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var signatureHelpOptions: SignatureHelpOptions - - public init(documentSelector: DocumentSelector? = nil, signatureHelpOptions: SignatureHelpOptions) { - self.textDocumentRegistrationOptions = - TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.signatureHelpOptions = signatureHelpOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let signatureHelpOptions = SignatureHelpOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.signatureHelpOptions = signatureHelpOptions - - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if case .dictionary(let dictionary) = signatureHelpOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - return .dictionary(dict) - } -} - -/// Folding range registration options. -public struct FoldingRangeRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var foldingRangeOptions: FoldingRangeOptions - - public init(documentSelector: DocumentSelector? = nil, foldingRangeOptions: FoldingRangeOptions) { - self.textDocumentRegistrationOptions = - TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.foldingRangeOptions = foldingRangeOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - - /// Currently empty in the spec. - self.foldingRangeOptions = FoldingRangeOptions() - } - - public func encodeToLSPAny() -> LSPAny { - textDocumentRegistrationOptions.encodeToLSPAny() - // foldingRangeOptions is currently empty. - } -} - -public struct SemanticTokensRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable -{ - /// Method for registration, which defers from the actual requests' methods - /// since this registration handles multiple requests. - public static let method: String = "textDocument/semanticTokens" - - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var semanticTokenOptions: SemanticTokensOptions - - public init(documentSelector: DocumentSelector? = nil, semanticTokenOptions: SemanticTokensOptions) { - self.textDocumentRegistrationOptions = - TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.semanticTokenOptions = semanticTokenOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - - guard let semanticTokenOptions = SemanticTokensOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.semanticTokenOptions = semanticTokenOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - if case .dictionary(let dictionary) = semanticTokenOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - return .dictionary(dict) - } -} - -public struct InlayHintRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol, Hashable { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var inlayHintOptions: InlayHintOptions - - public init( - documentSelector: DocumentSelector? = nil, - inlayHintOptions: InlayHintOptions - ) { - textDocumentRegistrationOptions = TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.inlayHintOptions = inlayHintOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - self.inlayHintOptions = InlayHintOptions() - - if case .bool(let resolveProvider) = dictionary["resolveProvider"] { - self.inlayHintOptions.resolveProvider = resolveProvider - } - - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let resolveProvider = inlayHintOptions.resolveProvider { - dict["resolveProvider"] = .bool(resolveProvider) - } - - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - return .dictionary(dict) - } -} - -/// Describe options to be used when registering for pull diagnostics. Since LSP 3.17.0 -public struct DiagnosticRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var diagnosticOptions: DiagnosticOptions - - public init( - documentSelector: DocumentSelector? = nil, - diagnosticOptions: DiagnosticOptions - ) { - textDocumentRegistrationOptions = TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.diagnosticOptions = diagnosticOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - - guard let diagnosticOptions = DiagnosticOptions(fromLSPDictionary: dictionary) else { - return nil - } - self.diagnosticOptions = diagnosticOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - if case .dictionary(let dictionary) = diagnosticOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - return .dictionary(dict) - } -} - -/// Describe options to be used when registering for code lenses. -public struct CodeLensRegistrationOptions: RegistrationOptions, TextDocumentRegistrationOptionsProtocol { - public var textDocumentRegistrationOptions: TextDocumentRegistrationOptions - public var codeLensOptions: CodeLensOptions - - public init( - documentSelector: DocumentSelector? = nil, - codeLensOptions: CodeLensOptions - ) { - textDocumentRegistrationOptions = TextDocumentRegistrationOptions(documentSelector: documentSelector) - self.codeLensOptions = codeLensOptions - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - self.codeLensOptions = CodeLensOptions() - - if case .bool(let resolveProvider) = dictionary["resolveProvider"] { - self.codeLensOptions.resolveProvider = resolveProvider - } - - guard let textDocumentRegistrationOptions = TextDocumentRegistrationOptions(fromLSPDictionary: dictionary) else { - return nil - } - - self.textDocumentRegistrationOptions = textDocumentRegistrationOptions - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let resolveProvider = codeLensOptions.resolveProvider { - dict["resolveProvider"] = .bool(resolveProvider) - } - - if case .dictionary(let dictionary) = textDocumentRegistrationOptions.encodeToLSPAny() { - dict.merge(dictionary) { (current, _) in current } - } - - return .dictionary(dict) - } -} - -/// Describe options to be used when registering for file system change events. -public struct DidChangeWatchedFilesRegistrationOptions: RegistrationOptions { - /// The watchers to register. - public var watchers: [FileSystemWatcher] - - public init(watchers: [FileSystemWatcher]) { - self.watchers = watchers - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let watchersArray = dictionary["watchers"], - let watchers = [FileSystemWatcher](fromLSPArray: watchersArray) - else { - return nil - } - - self.watchers = watchers - } - - public func encodeToLSPAny() -> LSPAny { - .dictionary(["watchers": watchers.encodeToLSPAny()]) - } -} - -/// Execute command registration options. -public struct ExecuteCommandRegistrationOptions: RegistrationOptions { - /// The commands to be executed on this server. - public var commands: [String] - - public init(commands: [String]) { - self.commands = commands - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard let commandsArray = dictionary["commands"], - let commands = [String](fromLSPArray: commandsArray) - else { - return nil - } - - self.commands = commands - } - - public func encodeToLSPAny() -> LSPAny { - .dictionary(["commands": commands.encodeToLSPAny()]) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenModifiers.swift b/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenModifiers.swift deleted file mode 100644 index b623e52d1..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenModifiers.swift +++ /dev/null @@ -1,102 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// Additional metadata about a token. -/// -/// Similar to `SemanticTokenTypes`, the bit indices should -/// be numbered starting at 0. -public struct SemanticTokenModifiers: OptionSet, Hashable, Sendable { - public let rawValue: UInt32 - - public init(rawValue: UInt32) { - self.rawValue = rawValue - } - - public static let declaration = Self(rawValue: 1 << 0) - public static let definition = Self(rawValue: 1 << 1) - public static let readonly = Self(rawValue: 1 << 2) - public static let `static` = Self(rawValue: 1 << 3) - public static let deprecated = Self(rawValue: 1 << 4) - public static let abstract = Self(rawValue: 1 << 5) - public static let async = Self(rawValue: 1 << 6) - public static let modification = Self(rawValue: 1 << 7) - public static let documentation = Self(rawValue: 1 << 8) - public static let defaultLibrary = Self(rawValue: 1 << 9) - - // The following are LSP extensions from clangd - public static let deduced = Self(rawValue: 1 << 10) - public static let virtual = Self(rawValue: 1 << 11) - public static let dependentName = Self(rawValue: 1 << 12) - public static let usedAsMutableReference = Self(rawValue: 1 << 13) - public static let usedAsMutablePointer = Self(rawValue: 1 << 14) - public static let constructorOrDestructor = Self(rawValue: 1 << 15) - public static let userDefined = Self(rawValue: 1 << 16) - public static let functionScope = Self(rawValue: 1 << 17) - public static let classScope = Self(rawValue: 1 << 18) - public static let fileScope = Self(rawValue: 1 << 19) - public static let globalScope = Self(rawValue: 1 << 20) - - public var name: String? { - switch self { - case .declaration: return "declaration" - case .definition: return "definition" - case .readonly: return "readonly" - case .static: return "static" - case .deprecated: return "deprecated" - case .abstract: return "abstract" - case .async: return "async" - case .modification: return "modification" - case .documentation: return "documentation" - case .defaultLibrary: return "defaultLibrary" - case .deduced: return "deduced" - case .virtual: return "virtual" - case .dependentName: return "dependentName" - case .usedAsMutableReference: return "usedAsMutableReference" - case .usedAsMutablePointer: return "usedAsMutablePointer" - case .constructorOrDestructor: return "constructorOrDestructor" - case .userDefined: return "userDefined" - case .functionScope: return "functionScope" - case .classScope: return "classScope" - case .fileScope: return "fileScope" - case .globalScope: return "globalScope" - default: return nil - } - } - - /// All available modifiers, in ascending order of the bit index - /// they are represented with (starting at the rightmost bit). - public static let all: [Self] = [ - .declaration, - .definition, - .readonly, - .static, - .deprecated, - .abstract, - .async, - .modification, - .documentation, - .defaultLibrary, - .deduced, - .virtual, - .dependentName, - .usedAsMutableReference, - .usedAsMutablePointer, - .constructorOrDestructor, - .userDefined, - .functionScope, - .classScope, - .fileScope, - .globalScope, - ] -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenTypes.swift b/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenTypes.swift deleted file mode 100644 index 0deafb5a8..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokenTypes.swift +++ /dev/null @@ -1,94 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// The predefined token type values -/// -/// The protocol defines a set of token types and modifiers but clients are -/// allowed to extend these and announce the values they support in the -/// corresponding client capability. -public struct SemanticTokenTypes: Hashable, Sendable { - public let name: String - public init(_ name: String) { - self.name = name - } - - public static let namespace = Self("namespace") - /// Represents a generic type. Acts as a fallback for types which - /// can't be mapped to a specific type like class or enum. - public static let type = Self("type") - public static let `class` = Self("class") - public static let `enum` = Self("enum") - public static let interface = Self("interface") - public static let `struct` = Self("struct") - public static let typeParameter = Self("typeParameter") - public static let parameter = Self("parameter") - public static let variable = Self("variable") - public static let property = Self("property") - public static let enumMember = Self("enumMember") - public static let event = Self("event") - public static let function = Self("function") - public static let method = Self("method") - public static let macro = Self("macro") - public static let keyword = Self("keyword") - public static let modifier = Self("modifier") - public static let comment = Self("comment") - public static let string = Self("string") - public static let number = Self("number") - public static let regexp = Self("regexp") - public static let `operator` = Self("operator") - /// since 3.17.0 - public static let decorator = Self("decorator") - - // The following are LSP extensions from clangd - public static let bracket = Self("bracket") - public static let label = Self("label") - public static let concept = Self("concept") - public static let unknown = Self("unknown") - - /// An identifier that hasn't been further classified - /// - /// **(LSP Extension)** - public static let identifier = Self("identifier") - - public static let all: [Self] = [ - .namespace, - .type, - .class, - .enum, - .interface, - .struct, - .typeParameter, - .parameter, - .variable, - .property, - .enumMember, - .event, - .function, - .method, - .macro, - .keyword, - .modifier, - .comment, - .string, - .number, - .regexp, - .operator, - .decorator, - .bracket, - .label, - .concept, - .unknown, - .identifier, - ] -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokens.swift b/Sources/LanguageServerProtocol/SupportTypes/SemanticTokens.swift deleted file mode 100644 index b6482d50d..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/SemanticTokens.swift +++ /dev/null @@ -1,67 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The legend for a server's encoding of semantic tokens. -public struct SemanticTokensLegend: Codable, Hashable, LSPAnyCodable, Sendable { - /// The token types for a server. - /// - /// Token types are looked up by indexing into this array, e.g. a `tokenType` - /// of `1` means `tokenTypes[1]`. - public var tokenTypes: [String] - - /// The token modifies for a server. - /// - /// A token can have multiple modifiers, so a `tokenModifier` is viewed - /// as a binary bit field and then indexed into this array, e.g. a - /// `tokenModifier` of `3` is viewed as binary `0b00000011` which - /// means `[tokenModifiers[0], tokenModifiers[1]]` because - /// bits 0 and 1 are set. - public var tokenModifiers: [String] - - public init(tokenTypes: [String], tokenModifiers: [String]) { - self.tokenTypes = tokenTypes - self.tokenModifiers = tokenModifiers - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - self.tokenTypes = [] - if let tokenTypesAny = dictionary["tokenTypes"], - let tokenTypes = [String](fromLSPArray: tokenTypesAny) - { - self.tokenTypes = tokenTypes - } - - self.tokenModifiers = [] - if let tokenModifiersAny = dictionary["tokenModifiers"], - let tokenModifiers = [String](fromLSPArray: tokenModifiersAny) - { - self.tokenModifiers = tokenModifiers - } - } - - public func encodeToLSPAny() -> LSPAny { - .dictionary([ - "tokenTypes": tokenTypes.encodeToLSPAny(), - "tokenModifiers": tokenModifiers.encodeToLSPAny(), - ]) - } -} - -/// The encoding format for semantic tokens. Currently only `relative` is supported. -public struct TokenFormat: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: String - public init(rawValue: String) { - self.rawValue = rawValue - } - - public static let relative: TokenFormat = TokenFormat(rawValue: "relative") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/ServerCapabilities.swift b/Sources/LanguageServerProtocol/SupportTypes/ServerCapabilities.swift deleted file mode 100644 index 0425df6e7..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/ServerCapabilities.swift +++ /dev/null @@ -1,1260 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Capabilities provided by the language server. -public struct ServerCapabilities: Codable, Hashable, Sendable { - - /// The position encoding the server picked from the encodings offered - /// by the client via the client capability `general.positionEncodings`. - /// - /// If the client didn't provide any position encodings the only valid - /// value that a server can return is 'utf-16'. - /// - /// If omitted it defaults to 'utf-16'. - public var positionEncoding: PositionEncodingKind? - - /// Defines how text documents are synced. Is either a detailed structure defining each notification or - /// for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`. - public var textDocumentSync: TextDocumentSync? - - /// Defines how notebook documents are synced. - public var notebookDocumentSync: NotebookDocumentSyncAndStaticRegistrationOptions? - - /// Whether the server provides "textDocument/hover". - public var hoverProvider: ValueOrBool? - - /// Whether the server provides code-completion. - public var completionProvider: CompletionOptions? - - /// The server provides signature help support. - public var signatureHelpProvider: SignatureHelpOptions? - - /// Whether the server provides "textDocument/definition". - public var definitionProvider: ValueOrBool? - - /// The server provides Goto Type Definition support. - public var typeDefinitionProvider: ValueOrBool? - - /// Whether the server provides "textDocument/implementation". - public var implementationProvider: ValueOrBool? - - /// Whether the server provides "textDocument/references". - public var referencesProvider: ValueOrBool? - - /// Whether the server provides "textDocument/documentHighlight". - public var documentHighlightProvider: ValueOrBool? - - /// Whether the server provides "textDocument/documentSymbol" - public var documentSymbolProvider: ValueOrBool? - - /// The server provides workspace symbol support. - public var workspaceSymbolProvider: ValueOrBool? - - /// Whether the server provides "textDocument/codeAction". - public var codeActionProvider: ValueOrBool? - - /// The server provides code lens. - public var codeLensProvider: CodeLensOptions? - - /// Whether the server provides "textDocument/formatting". - public var documentFormattingProvider: ValueOrBool? - - /// Whether the server provides "textDocument/rangeFormatting". - public var documentRangeFormattingProvider: ValueOrBool? - - /// Whether the server provides "textDocument/onTypeFormatting". - public var documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions? - - /// The server provides rename support. RenameOptions may only be specified if the client states that it supports `prepareSupport` in its initial `initialize` request. - public var renameProvider: ValueOrBool? - - /// The server provides document link support. - public var documentLinkProvider: DocumentLinkOptions? - - /// Whether the server provides "textDocument/documentColor" and "textDocument/colorPresentation". - public var colorProvider: ValueOrBool? - - /// Whether the server provides "textDocument/foldingRange". - public var foldingRangeProvider: ValueOrBool? - - public var declarationProvider: ValueOrBool? - - /// Whether the server provides "workspace/executeCommand". - public var executeCommandProvider: ExecuteCommandOptions? - - public var workspace: WorkspaceServerCapabilities? - - /// Whether the server provides `textDocument/prepareCallHierarchy` and related - /// call hierarchy requests. - public var callHierarchyProvider: ValueOrBool? - - /// Whether the server provides `textDocument/prepareTypeHierarchy` and related - /// type hierarchy requests. - public var typeHierarchyProvider: ValueOrBool? - - /// Whether the server supports the `textDocument/semanticTokens` family of - /// requests. - public var semanticTokensProvider: SemanticTokensOptions? - - /// Whether the server supports the `textDocument/inlayHint` family of requests. - public var inlayHintProvider: ValueOrBool? - - /// Whether the server supports the `textDocument/diagnostic` request. - public var diagnosticProvider: DiagnosticOptions? - - /// Whether the server provides selection range support. - public var selectionRangeProvider: ValueOrBool? - - /// Whether the server provides link editing range support. - public var linkedEditingRangeProvider: ValueOrBool? - - /// Whether server provides moniker support. - public var monikerProvider: ValueOrBool? - - /// The server provides inline values. - public var inlineValueProvider: ValueOrBool? - - public var experimental: LSPAny? - - public init( - positionEncoding: PositionEncodingKind? = nil, - textDocumentSync: TextDocumentSync? = nil, - notebookDocumentSync: NotebookDocumentSyncAndStaticRegistrationOptions? = nil, - hoverProvider: ValueOrBool? = nil, - completionProvider: CompletionOptions? = nil, - signatureHelpProvider: SignatureHelpOptions? = nil, - definitionProvider: ValueOrBool? = nil, - typeDefinitionProvider: ValueOrBool? = nil, - implementationProvider: ValueOrBool? = nil, - referencesProvider: ValueOrBool? = nil, - documentHighlightProvider: ValueOrBool? = nil, - documentSymbolProvider: ValueOrBool? = nil, - workspaceSymbolProvider: ValueOrBool? = nil, - codeActionProvider: ValueOrBool? = nil, - codeLensProvider: CodeLensOptions? = nil, - documentFormattingProvider: ValueOrBool? = nil, - documentRangeFormattingProvider: ValueOrBool? = nil, - documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions? = nil, - renameProvider: ValueOrBool? = nil, - documentLinkProvider: DocumentLinkOptions? = nil, - colorProvider: ValueOrBool? = nil, - foldingRangeProvider: ValueOrBool? = nil, - declarationProvider: ValueOrBool? = nil, - executeCommandProvider: ExecuteCommandOptions? = nil, - workspace: WorkspaceServerCapabilities? = nil, - callHierarchyProvider: ValueOrBool? = nil, - typeHierarchyProvider: ValueOrBool? = nil, - semanticTokensProvider: SemanticTokensOptions? = nil, - inlayHintProvider: ValueOrBool? = nil, - diagnosticProvider: DiagnosticOptions? = nil, - selectionRangeProvider: ValueOrBool? = nil, - linkedEditingRangeProvider: ValueOrBool? = nil, - monikerProvider: ValueOrBool? = nil, - inlineValueProvider: ValueOrBool? = nil, - experimental: LSPAny? = nil - ) { - self.positionEncoding = positionEncoding - self.textDocumentSync = textDocumentSync - self.notebookDocumentSync = notebookDocumentSync - self.hoverProvider = hoverProvider - self.completionProvider = completionProvider - self.signatureHelpProvider = signatureHelpProvider - self.definitionProvider = definitionProvider - self.typeDefinitionProvider = typeDefinitionProvider - self.implementationProvider = implementationProvider - self.referencesProvider = referencesProvider - self.documentHighlightProvider = documentHighlightProvider - self.documentSymbolProvider = documentSymbolProvider - self.workspaceSymbolProvider = workspaceSymbolProvider - self.codeActionProvider = codeActionProvider - self.codeLensProvider = codeLensProvider - self.documentFormattingProvider = documentFormattingProvider - self.documentRangeFormattingProvider = documentRangeFormattingProvider - self.documentOnTypeFormattingProvider = documentOnTypeFormattingProvider - self.renameProvider = renameProvider - self.documentLinkProvider = documentLinkProvider - self.colorProvider = colorProvider - self.foldingRangeProvider = foldingRangeProvider - self.declarationProvider = declarationProvider - self.executeCommandProvider = executeCommandProvider - self.workspace = workspace - self.callHierarchyProvider = callHierarchyProvider - self.typeHierarchyProvider = typeHierarchyProvider - self.semanticTokensProvider = semanticTokensProvider - self.inlayHintProvider = inlayHintProvider - self.diagnosticProvider = diagnosticProvider - self.selectionRangeProvider = selectionRangeProvider - self.linkedEditingRangeProvider = linkedEditingRangeProvider - self.experimental = experimental - self.monikerProvider = monikerProvider - self.inlineValueProvider = inlineValueProvider - } -} - -public enum ValueOrBool: Codable, Hashable where ValueType: Hashable { - case bool(Bool) - case value(ValueType) - - /// A option is supported if either its bool value is `true` or the value is specified - public var isSupported: Bool { - switch self { - case .bool(let value): - return value - case .value(_): - return true - } - } - - public init(from decoder: Decoder) throws { - if let bool = try? Bool(from: decoder) { - self = .bool(bool) - } else if let value = try? ValueType(from: decoder) { - self = .value(value) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected Bool or \(ValueType.self)" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .bool(let bool): - try bool.encode(to: encoder) - case .value(let value): - try value.encode(to: encoder) - } - } -} - -extension ValueOrBool: Sendable where ValueType: Sendable {} - -public enum TextDocumentSync: Codable, Hashable, Sendable { - case options(TextDocumentSyncOptions) - case kind(TextDocumentSyncKind) - - public init(from decoder: Decoder) throws { - if let options = try? TextDocumentSyncOptions(from: decoder) { - self = .options(options) - } else if let kind = try? TextDocumentSyncKind(from: decoder) { - self = .kind(kind) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected TextDocumentSyncOptions or TextDocumentSyncKind" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .options(let options): - try options.encode(to: encoder) - case .kind(let kind): - try kind.encode(to: encoder) - } - } -} - -/// The LSP spec has two definitions of `TextDocumentSyncOptions`, one -/// with `willSave` etc. and one that only contains `openClose` and `change`. -/// Based on the VSCode implementation, the definition that contains `willSave` -/// appears to be the correct one, so we use that one as well. -public struct TextDocumentSyncOptions: Codable, Hashable, Sendable { - - /// Open and close notifications are sent to the server. - /// If omitted open close notifications should not be sent. - public var openClose: Bool? - - /// Change notifications are sent to the server. See - /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full and - /// TextDocumentSyncKind.Incremental. If omitted it defaults to - /// TextDocumentSyncKind.None. - public var change: TextDocumentSyncKind? - - // NOTE: The following properties are not - - /// Whether will-save notifications should be sent to the server. - public var willSave: Bool? - - /// Whether will-save-wait-until notifications should be sent to the server. - public var willSaveWaitUntil: Bool? - - public struct SaveOptions: Codable, Hashable, Sendable { - - /// Whether the client should include the file content in save notifications. - public var includeText: Bool? - - public init(includeText: Bool? = nil) { - self.includeText = includeText - } - } - - /// Whether save notifications should be sent to the server. - public var save: ValueOrBool? - - public init( - openClose: Bool? = true, - change: TextDocumentSyncKind? = .incremental, - willSave: Bool? = true, - willSaveWaitUntil: Bool? = false, - save: ValueOrBool? = .value(SaveOptions(includeText: false)) - ) { - self.openClose = openClose - self.change = change - self.willSave = willSave - self.willSaveWaitUntil = willSaveWaitUntil - self.save = save - } - - public init(from decoder: Decoder) throws { - do { - let container = try decoder.container(keyedBy: CodingKeys.self) - self.openClose = try container.decodeIfPresent(Bool.self, forKey: .openClose) - self.change = try container.decodeIfPresent(TextDocumentSyncKind.self, forKey: .change) - self.willSave = try container.decodeIfPresent(Bool.self, forKey: .willSave) - self.willSaveWaitUntil = try container.decodeIfPresent(Bool.self, forKey: .willSaveWaitUntil) - self.save = try container.decodeIfPresent(ValueOrBool.self, forKey: .save) - return - } catch {} - do { - // Try decoding self as standalone TextDocumentSyncKind - self.change = try TextDocumentSyncKind(from: decoder) - return - } catch {} - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected TextDocumentSyncOptions or TextDocumentSyncKind" - ) - throw DecodingError.dataCorrupted(context) - } -} - -public enum TextDocumentSyncKind: Int, Codable, Hashable, Sendable { - - /// Documents should not be synced at all. - case none = 0 - - /// Documents are synced by always sending the full content of the document. - case full = 1 - - /// Documents are synced by sending the full content on open. - /// After that only incremental updates to the document are sent. - case incremental = 2 -} - -public enum NotebookFilter: Codable, Hashable, Sendable { - case string(String) - case documentFilter(DocumentFilter) - - public init(from decoder: Decoder) throws { - if let string = try? String(from: decoder) { - self = .string(string) - } else if let documentFilter = try? DocumentFilter(from: decoder) { - self = .documentFilter(documentFilter) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected String or DocumentFilter" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .string(let string): - try string.encode(to: encoder) - case .documentFilter(let documentFilter): - try documentFilter.encode(to: encoder) - } - } -} -public typealias NotebookSelector = [NotebookFilter] - -public struct NotebookDocumentSyncAndStaticRegistrationOptions: Codable, Hashable, Sendable { - /// The notebooks to be synced - public var notebookSelector: NotebookSelector - - /// Whether save notification should be forwarded to - /// the server. Will only be honored if mode === `notebook`. - public var save: Bool? - - /// The id used to register the request. The id can be used to deregister the request again. See also Registration#id - public var id: String? - - public init( - notebookSelector: NotebookSelector, - save: Bool? = nil, - id: String? = nil - ) { - self.notebookSelector = notebookSelector - self.save = save - self.id = id - } -} - -public protocol WorkDoneProgressOptions { - var workDoneProgress: Bool? { get } -} - -public struct HoverOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct CompletionItemOptions: LSPAnyCodable, Codable, Hashable, Sendable { - /// The server has support for completion item label - /// details (see also `CompletionItemLabelDetails`) when receiving - /// a completion item in a resolve call. - public var labelDetailsSupport: Bool? - - public init( - labelDetailsSupport: Bool? = false - ) { - self.labelDetailsSupport = labelDetailsSupport - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if case .bool(let labelDetailsSupport) = dictionary["labelDetailsSupport"] { - self.labelDetailsSupport = labelDetailsSupport - } - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let labelDetailsSupport { - dict["labelDetailsSupport"] = .bool(labelDetailsSupport) - } - - return .dictionary(dict) - } -} - -public struct CompletionOptions: WorkDoneProgressOptions, Codable, LSPAnyCodable, Hashable, Sendable { - /// Whether to use `textDocument/resolveCompletion` - public var resolveProvider: Bool? - - /// The characters that should trigger automatic completion. - public var triggerCharacters: [String]? - - /// The list of all possible characters that commit a completion. - public var allCommitCharacters: [String]? - - /// The server supports the following `CompletionItem` specific capabilities. - public var completionItem: CompletionItemOptions? - - public var workDoneProgress: Bool? - - public init( - resolveProvider: Bool? = false, - triggerCharacters: [String]? = nil, - allCommitCharacters: [String]? = nil, - completionItem: CompletionItemOptions? = nil, - workDoneProgress: Bool? = nil - ) { - self.resolveProvider = resolveProvider - self.triggerCharacters = triggerCharacters - self.allCommitCharacters = allCommitCharacters - self.completionItem = completionItem - self.workDoneProgress = workDoneProgress - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if case .bool(let value) = dictionary["resolveProvider"] { - resolveProvider = value - } - - if let arrayAny = dictionary["triggerCharacters"] { - triggerCharacters = [String](fromLSPArray: arrayAny) - } - - if let arrayAny = dictionary["allCommitCharacters"] { - allCommitCharacters = [String](fromLSPArray: arrayAny) - } - - if case .dictionary(let dict) = dictionary["completionItem"] { - completionItem = CompletionItemOptions(fromLSPDictionary: dict) - } - - if case .bool(let value) = dictionary["workDoneProgress"] { - workDoneProgress = value - } - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let resolveProvider { - dict["resolveProvider"] = .bool(resolveProvider) - } - - if let triggerCharacters { - dict["triggerCharacters"] = triggerCharacters.encodeToLSPAny() - } - - if let allCommitCharacters { - dict["allCommitCharacters"] = allCommitCharacters.encodeToLSPAny() - } - - if let completionItem { - dict["completionItem"] = completionItem.encodeToLSPAny() - } - - if let workDoneProgress { - dict["workDoneProgress"] = .bool(workDoneProgress) - } - - return .dictionary(dict) - } -} - -public struct DefinitionOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct ReferenceOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentHighlightOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentSymbolOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentFormattingOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentRangeFormattingOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - public var workDoneProgress: Bool? - - public init( - workDoneProgress: Bool? = nil - ) { - self.workDoneProgress = workDoneProgress - } -} - -public struct FoldingRangeOptions: Codable, Hashable, Sendable { - /// Currently empty in the spec. - public init() {} -} - -public struct SignatureHelpOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// The characters that trigger signature help automatically. - public var triggerCharacters: [String]? - - /// List of characters that re-trigger signature help. - /// - /// These trigger characters are only active when signature help is already - /// showing. All trigger characters are also counted as re-trigger - /// characters. - public var retriggerCharacters: [String]? - - public var workDoneProgress: Bool? - - public init( - triggerCharacters: [String]? = nil, - retriggerCharacters: [String]? = nil - ) { - self.triggerCharacters = triggerCharacters - self.retriggerCharacters = retriggerCharacters - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if let arrayAny = dictionary["triggerCharacters"] { - triggerCharacters = [String](fromLSPArray: arrayAny) - } - - if let arrayAny = dictionary["retriggerCharacters"] { - retriggerCharacters = [String](fromLSPArray: arrayAny) - } - - if case .bool(let value) = dictionary["workDoneProgress"] { - workDoneProgress = value - } - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let triggerCharacters { - dict["triggerCharacters"] = triggerCharacters.encodeToLSPAny() - } - - if let retriggerCharacters { - dict["retriggerCharacters"] = retriggerCharacters.encodeToLSPAny() - } - - if let workDoneProgress { - dict["workDoneProgress"] = .bool(workDoneProgress) - } - - return .dictionary(dict) - } -} - -public struct DocumentFilter: Codable, Hashable, Sendable { - /// A language id, like `typescript`. - public var language: String? - - /// A Uri scheme, like `file` or `untitled`. - public var scheme: String? - - /// A glob pattern, like `*.{ts,js}`. - /// - /// Glob patterns can have the following syntax: - /// - `*` to match one or more characters in a path segment - /// - `?` to match on one character in a path segment - /// - `**` to match any number of path segments, including none - /// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files) - /// - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) - /// - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) - public var pattern: String? - - public init(language: String? = nil, scheme: String? = nil, pattern: String? = nil) { - self.language = language - self.scheme = scheme - self.pattern = pattern - } -} - -extension DocumentFilter: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if let languageValue = dictionary[CodingKeys.language.stringValue] { - guard case .string(let language) = languageValue else { return nil } - self.language = language - } else { - self.language = nil - } - if let schemeValue = dictionary[CodingKeys.scheme.stringValue] { - guard case .string(let scheme) = schemeValue else { return nil } - self.scheme = scheme - } else { - self.scheme = nil - } - if let patternValue = dictionary[CodingKeys.pattern.stringValue] { - guard case .string(let pattern) = patternValue else { return nil } - self.pattern = pattern - } else { - self.pattern = nil - } - } - public func encodeToLSPAny() -> LSPAny { - var dict = [String: LSPAny]() - if let language = language { - dict[CodingKeys.language.stringValue] = .string(language) - } - if let scheme = scheme { - dict[CodingKeys.scheme.stringValue] = .string(scheme) - } - if let pattern = pattern { - dict[CodingKeys.pattern.stringValue] = .string(pattern) - } - return .dictionary(dict) - } -} - -public typealias DocumentSelector = [DocumentFilter] - -public struct TextDocumentAndStaticRegistrationOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// A document selector to identify the scope of the registration. If set to null the document selector provided on the client side will be used. - public var documentSelector: DocumentSelector? - - /// The id used to register the request. The id can be used to deregister the request again. See also Registration#id - public var id: String? - - public var workDoneProgress: Bool? - - public init( - documentSelector: DocumentSelector? = nil, - id: String? = nil, - workDoneProgress: Bool? = nil - ) { - self.documentSelector = documentSelector - self.id = id - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentOnTypeFormattingOptions: Codable, Hashable, Sendable { - - /// A character that should trigger formatting (e.g. '}'). - public var firstTriggerCharacter: String - - /// Additional triggers. - /// - /// - note: The lack of plural matches the protocol. - public var moreTriggerCharacter: [String]? - - public init(triggerCharacters: [String]) { - self.firstTriggerCharacter = triggerCharacters.first! - self.moreTriggerCharacter = Array(triggerCharacters.dropFirst()) - } -} - -/// Wrapper type for a server's CodeActions' capabilities. -/// If the client supports CodeAction literals, the server can return specific information about -/// how CodeActions will be sent. Otherwise, the server's capabilities are determined by a boolean. -public enum CodeActionServerCapabilities: Codable, Hashable, Sendable { - - case supportsCodeActionRequests(Bool) - case supportsCodeActionRequestsWithLiterals(CodeActionOptions) - - public init( - clientCapabilities: TextDocumentClientCapabilities.CodeAction?, - codeActionOptions: CodeActionOptions, - supportsCodeActions: Bool - ) { - if clientCapabilities?.codeActionLiteralSupport != nil { - self = .supportsCodeActionRequestsWithLiterals(codeActionOptions) - } else { - self = .supportsCodeActionRequests(supportsCodeActions) - } - } - - public init(from decoder: Decoder) throws { - let container = try decoder.singleValueContainer() - if let supportsCodeActions = try? container.decode(Bool.self) { - self = .supportsCodeActionRequests(supportsCodeActions) - } else if let codeActionOptions = try? container.decode(CodeActionOptions.self) { - self = .supportsCodeActionRequestsWithLiterals(codeActionOptions) - } else { - let error = "CodeActionServerCapabilities cannot be decoded: Unrecognized type." - throw DecodingError.dataCorruptedError(in: container, debugDescription: error) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - switch self { - case .supportsCodeActionRequestsWithLiterals(let codeActionOptions): - try container.encode(codeActionOptions) - case .supportsCodeActionRequests(let supportCodeActions): - try container.encode(supportCodeActions) - } - } -} - -public struct CodeActionOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - - /// CodeActionKinds that this server may return. - public var codeActionKinds: [CodeActionKind]? - - /// The server provides support to resolve additional - /// information for a code action. - public var resolveProvider: Bool? - - public var workDoneProgress: Bool? - - public init( - codeActionKinds: [CodeActionKind]?, - resolveProvider: Bool? = nil, - workDoneProgress: Bool? = nil - ) { - self.codeActionKinds = codeActionKinds - self.resolveProvider = resolveProvider - self.workDoneProgress = workDoneProgress - } -} - -public struct CodeLensOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// Code lens has a resolve provider as well. - public var resolveProvider: Bool? - - public var workDoneProgress: Bool? - - public init( - resolveProvider: Bool? = nil, - workDoneProgress: Bool? = nil - ) { - self.resolveProvider = resolveProvider - self.workDoneProgress = workDoneProgress - } -} - -public struct ExecuteCommandOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - - /// The commands to be executed on this server. - public var commands: [String] - - public var workDoneProgress: Bool? - - public init( - commands: [String], - workDoneProgress: Bool? = nil - ) { - self.commands = commands - self.workDoneProgress = workDoneProgress - } -} - -public struct RenameOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// Renames should be checked and tested before being executed. - public var prepareProvider: Bool? - - public var workDoneProgress: Bool? - - public init( - prepareProvider: Bool? = nil, - workDoneProgress: Bool? = nil - ) { - self.prepareProvider = prepareProvider - self.workDoneProgress = workDoneProgress - } -} - -public struct DocumentLinkOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// Document links have a resolve provider as well. - public var resolveProvider: Bool? - - public var workDoneProgress: Bool? - - public init( - resolveProvider: Bool? = nil, - workDoneProgress: Bool? = nil - ) { - self.resolveProvider = resolveProvider - self.workDoneProgress = workDoneProgress - } -} - -public struct SemanticTokensOptions: WorkDoneProgressOptions, Codable, Hashable, LSPAnyCodable, Sendable { - - public struct SemanticTokensRangeOptions: Equatable, Hashable, Codable, LSPAnyCodable, Sendable { - public init() { - // Empty in the LSP 3.16 spec. - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - self.init() - } - - public func encodeToLSPAny() -> LSPAny { - .dictionary([:]) - } - } - - public struct SemanticTokensFullOptions: Equatable, Hashable, Codable, LSPAnyCodable, Sendable { - /// The server supports deltas for full documents. - public var delta: Bool? - - public init(delta: Bool? = nil) { - self.delta = delta - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - self.delta = nil - - if case .bool(let value) = dictionary["delta"] { - self.delta = value - } - } - - public func encodeToLSPAny() -> LSPAny { - guard let delta else { - return .dictionary([:]) - } - - return .dictionary(["delta": .bool(delta)]) - } - } - - /// The legend used by the server. - public var legend: SemanticTokensLegend - - /// Server supports providing semantic tokens for a specific range - /// of a document. - public var range: ValueOrBool? - - /// Server supports providing semantic tokens for a full document. - public var full: ValueOrBool? - - public var workDoneProgress: Bool? - - public init( - legend: SemanticTokensLegend, - range: ValueOrBool? = nil, - full: ValueOrBool? = nil, - workDoneProgress: Bool? = nil - ) { - self.legend = legend - self.range = range - self.full = full - self.workDoneProgress = workDoneProgress - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard case .dictionary(let dict) = dictionary["legend"], - let legend = SemanticTokensLegend(fromLSPDictionary: dict) - else { - return nil - } - - self.legend = legend - - switch dictionary["range"] { - case .bool(let value): - self.range = .bool(value) - case .dictionary(let dict): - if let value = SemanticTokensRangeOptions(fromLSPDictionary: dict) { - self.range = .value(value) - } - default: - self.range = nil - } - - switch dictionary["full"] { - case .bool(let value): - self.full = .bool(value) - case .dictionary(let dict): - if let value = SemanticTokensFullOptions(fromLSPDictionary: dict) { - self.full = .value(value) - } - default: - self.full = nil - } - - if case .bool(let value) = dictionary["workDoneProgress"] { - self.workDoneProgress = value - } - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - dict["legend"] = legend.encodeToLSPAny() - - if let range { - dict["range"] = - switch range { - case .bool(let value): - .bool(value) - case .value(let rangeOptions): - rangeOptions.encodeToLSPAny() - } - } - - if let full { - dict["full"] = - switch full { - case .bool(let value): - .bool(value) - case .value(let fullOptions): - fullOptions.encodeToLSPAny() - } - } - - if let workDoneProgress { - dict["workDoneProgress"] = .bool(workDoneProgress) - } - - return .dictionary(dict) - } - -} - -public struct InlayHintOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// The server provides support to resolve additional information - /// for an inlay hint item. - public var resolveProvider: Bool? - - /// A document selector to identify the scope of the registration. If set to null the document selector provided on the client side will be used. - public var documentSelector: DocumentSelector? - - /// The id used to register the request. The id can be used to deregister the request again. See also Registration#id - public var id: String? - - public var workDoneProgress: Bool? - - public init( - resolveProvider: Bool? = nil, - documentSelector: DocumentSelector? = nil, - id: String? = nil, - workDoneProgress: Bool? = nil - ) { - self.resolveProvider = resolveProvider - self.documentSelector = documentSelector - self.id = id - self.workDoneProgress = workDoneProgress - } -} - -public struct WorkspaceSymbolOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// The server provides support to resolve additional information - /// for an inlay hint item. - public var resolveProvider: Bool? - - public var workDoneProgress: Bool? - - public init( - resolveProvider: Bool? = nil, - workDoneProgress: Bool? = nil - ) { - self.resolveProvider = resolveProvider - self.workDoneProgress = workDoneProgress - } -} - -public struct MonikerOptions: WorkDoneProgressOptions, Codable, Hashable, Sendable { - /// A document selector to identify the scope of the registration. If set to null the document selector provided on the client side will be used. - public var documentSelector: DocumentSelector? - - public var workDoneProgress: Bool? - - public init( - documentSelector: DocumentSelector? = nil, - workDoneProgress: Bool? = nil - ) { - self.documentSelector = documentSelector - self.workDoneProgress = workDoneProgress - } -} - -public struct DiagnosticOptions: WorkDoneProgressOptions, LSPAnyCodable, Codable, Hashable, Sendable { - /// An optional identifier under which the diagnostics are managed by the client. - public var identifier: String? - - /// Whether the language has inter file dependencies meaning that - /// editing code in one file can result in a different diagnostic - /// set in another file. Inter file dependencies are common for - /// most programming languages and typically uncommon for linters. - public var interFileDependencies: Bool - - /// The server provides support for workspace diagnostics as well. - public var workspaceDiagnostics: Bool - - /// The id used to register the request. The id can be used to deregister the request again. See also Registration#id - public var id: String? - - public var workDoneProgress: Bool? - - public init( - identifier: String? = nil, - interFileDependencies: Bool, - workspaceDiagnostics: Bool, - id: String? = nil, - workDoneProgress: Bool? = nil - ) { - self.identifier = identifier - self.interFileDependencies = interFileDependencies - self.workspaceDiagnostics = workspaceDiagnostics - self.id = id - self.workDoneProgress = workDoneProgress - } - - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - if case .string(let value) = dictionary["identifier"] { - self.identifier = value - } - - guard case .bool(let interFileDependencies) = dictionary["interFileDependencies"] else { - return nil - } - self.interFileDependencies = interFileDependencies - - guard case .bool(let workspaceDiagnostics) = dictionary["workspaceDiagnostics"] else { - return nil - } - self.workspaceDiagnostics = workspaceDiagnostics - - if case .string(let value) = dictionary["id"] { - self.id = value - } - - if case .bool(let value) = dictionary["workDoneProgress"] { - self.workDoneProgress = value - } - } - - public func encodeToLSPAny() -> LSPAny { - var dict: [String: LSPAny] = [:] - - if let identifier { - dict["identifier"] = .string(identifier) - } - - dict["interFileDependencies"] = .bool(interFileDependencies) - dict["workspaceDiagnostics"] = .bool(workspaceDiagnostics) - - if let id { - dict["id"] = .string(id) - } - - if let workDoneProgress = workDoneProgress { - dict["workDoneProgress"] = .bool(workDoneProgress) - } - - return .dictionary(dict) - } -} - -public struct WorkspaceServerCapabilities: Codable, Hashable, Sendable { - public struct WorkspaceFolders: Codable, Hashable, Sendable { - /// The server has support for workspace folders - public var supported: Bool? - - /// Whether the server wants to receive workspace folder change notifications. - /// - /// If a strings is provided the string is treated as a ID under which the notification is registered on the client side. The ID can be used to unregister for these events using the `client/unregisterCapability` request. - public var changeNotifications: ValueOrBool? - - public init(supported: Bool? = nil, changeNotifications: ValueOrBool? = nil) { - self.supported = supported - self.changeNotifications = changeNotifications - } - } - - public enum FileOperationPatternKind: String, Codable, Hashable { - /// The pattern matches a file only. - case file = "file" - /// The pattern matches a folder only. - case folder = "folder" - } - - public struct FileOperationPatternOptions: Codable, Hashable { - /// The pattern should be matched ignoring casing - public var ignoreCase: Bool? - - public init(ignoreCase: Bool? = nil) { - self.ignoreCase = ignoreCase - } - } - - public struct FileOperationPattern: Codable, Hashable { - /// The glob pattern to match. Glob patterns can have the following syntax: - /// - `*` to match one or more characters in a path segment - /// - `?` to match on one character in a path segment - /// - `**` to match any number of path segments, including none - /// - `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` - /// matches all TypeScript and JavaScript files) - /// - `[]` to declare a range of characters to match in a path segment - /// (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) - /// - `[!...]` to negate a range of characters to match in a path segment - /// (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but - /// not `example.0`) - public var glob: String - - /// Whether to match files or folders with this pattern. Matches both if undefined. - public var matches: FileOperationPatternKind? - - /// Additional options used during matching. - public var options: FileOperationPatternOptions? - - public init( - glob: String, - matches: FileOperationPatternKind? = nil, - options: FileOperationPatternOptions? = nil - ) { - self.glob = glob - self.matches = matches - self.options = options - } - } - - public struct FileOperationFilter: Codable, Hashable { - /// A Uri like `file` or `untitled`. - public var scheme: String? - - /// The actual file operation pattern. - public var pattern: FileOperationPattern - - public init( - scheme: String? = nil, - pattern: FileOperationPattern - ) { - self.scheme = scheme - self.pattern = pattern - } - } - - public struct FileOperationRegistrationOptions: Codable, Hashable { - /// The actual filters. - public var filters: [FileOperationFilter] - - public init( - filters: [FileOperationFilter] - ) { - self.filters = filters - } - } - - public struct FileOperationOptions: Codable, Hashable { - /// The server is interested in receiving didCreateFiles notifications. - public var didCreate: FileOperationRegistrationOptions? - - /// The server is interested in receiving willCreateFiles notifications. - public var willCreate: FileOperationRegistrationOptions? - - /// The server is interested in receiving didRenameFiles notifications. - public var didRename: FileOperationRegistrationOptions? - - /// The server is interested in receiving willRenameFiles notifications. - public var willRename: FileOperationRegistrationOptions? - - /// The server is interested in receiving didDeleteFiles notifications. - public var didDelete: FileOperationRegistrationOptions? - - /// The server is interested in receiving willDeleteFiles notifications. - public var willDelete: FileOperationRegistrationOptions? - } - - /// The server supports workspace folder. - public var workspaceFolders: WorkspaceFolders? - - public init(workspaceFolders: WorkspaceFolders? = nil) { - self.workspaceFolders = workspaceFolders - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/StringOrMarkupContent.swift b/Sources/LanguageServerProtocol/SupportTypes/StringOrMarkupContent.swift deleted file mode 100644 index 90cfd4465..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/StringOrMarkupContent.swift +++ /dev/null @@ -1,39 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum StringOrMarkupContent: Codable, Hashable, Sendable { - case string(String) - case markupContent(MarkupContent) - - public init(from decoder: Decoder) throws { - if let string = try? String(from: decoder) { - self = .string(string) - } else if let markupContent = try? MarkupContent(from: decoder) { - self = .markupContent(markupContent) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected String or MarkupContent" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .string(let string): - try string.encode(to: encoder) - case .markupContent(let markupContent): - try markupContent.encode(to: encoder) - } - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/SupportedCodeLensCommand.swift b/Sources/LanguageServerProtocol/SupportTypes/SupportedCodeLensCommand.swift deleted file mode 100644 index 9f4248055..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/SupportedCodeLensCommand.swift +++ /dev/null @@ -1,29 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Code lenses that LSP can annotate code with. -/// -/// Clients provide these as keys to the `supportedCommands` dictionary supplied -/// in the client's `InitializeRequest`. -public struct SupportedCodeLensCommand: Codable, Hashable, RawRepresentable, Sendable { - public var rawValue: String - - public init(rawValue: String) { - self.rawValue = rawValue - } - - /// Lens to run the application - public static let run: Self = Self(rawValue: "swift.run") - - /// Lens to debug the application - public static let debug: Self = Self(rawValue: "swift.debug") -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/SymbolKind.swift b/Sources/LanguageServerProtocol/SupportTypes/SymbolKind.swift deleted file mode 100644 index fe97b4914..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/SymbolKind.swift +++ /dev/null @@ -1,69 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A symbol kind. -/// -/// In LSP, this is an integer, so we don't use a closed set. -public struct SymbolKind: RawRepresentable, Codable, Hashable, Sendable { - - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - // MARK: LSP symbol kinds - - // LSP 1 kinds, guaranteed to be supported by all clients. - public static let file: SymbolKind = SymbolKind(rawValue: 1) - public static let module: SymbolKind = SymbolKind(rawValue: 2) - public static let namespace: SymbolKind = SymbolKind(rawValue: 3) - public static let package: SymbolKind = SymbolKind(rawValue: 4) - public static let `class`: SymbolKind = SymbolKind(rawValue: 5) - public static let method: SymbolKind = SymbolKind(rawValue: 6) - public static let property: SymbolKind = SymbolKind(rawValue: 7) - public static let field: SymbolKind = SymbolKind(rawValue: 8) - public static let constructor: SymbolKind = SymbolKind(rawValue: 9) - public static let `enum`: SymbolKind = SymbolKind(rawValue: 10) - public static let interface: SymbolKind = SymbolKind(rawValue: 11) - public static let function: SymbolKind = SymbolKind(rawValue: 12) - public static let variable: SymbolKind = SymbolKind(rawValue: 13) - public static let constant: SymbolKind = SymbolKind(rawValue: 14) - public static let string: SymbolKind = SymbolKind(rawValue: 15) - public static let number: SymbolKind = SymbolKind(rawValue: 16) - public static let boolean: SymbolKind = SymbolKind(rawValue: 17) - public static let array: SymbolKind = SymbolKind(rawValue: 18) - - // LSP 3+ - public static let object: SymbolKind = SymbolKind(rawValue: 19) - public static let key: SymbolKind = SymbolKind(rawValue: 20) - public static let null: SymbolKind = SymbolKind(rawValue: 21) - public static let enumMember: SymbolKind = SymbolKind(rawValue: 22) - public static let `struct`: SymbolKind = SymbolKind(rawValue: 23) - public static let event: SymbolKind = SymbolKind(rawValue: 24) - public static let `operator`: SymbolKind = SymbolKind(rawValue: 25) - public static let typeParameter: SymbolKind = SymbolKind(rawValue: 26) -} - -/// Symbol tags are extra annotations that tweak the rendering of a symbol. -/// -/// In LSP, this is an integer, so we don't use a closed set. -public struct SymbolTag: RawRepresentable, Codable, Hashable, Sendable { - public var rawValue: Int - - public init(rawValue: Int) { - self.rawValue = rawValue - } - - /// Render a symbol as obsolete, usually using a strike-out. - public static let deprecated: SymbolTag = SymbolTag(rawValue: 1) -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TestItem.swift b/Sources/LanguageServerProtocol/SupportTypes/TestItem.swift deleted file mode 100644 index a764dabc6..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TestItem.swift +++ /dev/null @@ -1,80 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public struct TestTag: Codable, Equatable, Sendable { - /// ID of the test tag. `TestTag` instances with the same ID are considered to be identical. - public var id: String - - public init(id: String) { - self.id = id - } -} - -/// A test item that can be shown an a client's test explorer or used to identify tests alongside a source file. -/// -/// A `TestItem` can represent either a test suite or a test itself, since they both have similar capabilities. -public struct TestItem: ResponseType, Equatable { - /// Identifier for the `TestItem`. - /// - /// This identifier uniquely identifies the test case or test suite. It can be used to run an individual test (suite). - public var id: String - - /// Display name describing the test. - public var label: String - - /// Optional description that appears next to the label. - public var description: String? - - /// A string that should be used when comparing this item with other items. - /// - /// When `nil` the `label` is used. - public var sortText: String? - - /// Whether the test is disabled. - public var disabled: Bool - - /// The type of test, eg. the testing framework that was used to declare the test. - public var style: String - - /// The location of the test item in the source code. - public var location: Location - - /// The children of this test item. - /// - /// For a test suite, this may contain the individual test cases or nested suites. - public var children: [TestItem] - - /// Tags associated with this test item. - public var tags: [TestTag] - - public init( - id: String, - label: String, - description: String? = nil, - sortText: String? = nil, - disabled: Bool, - style: String, - location: Location, - children: [TestItem], - tags: [TestTag] - ) { - self.id = id - self.label = label - self.description = description - self.sortText = sortText - self.disabled = disabled - self.style = style - self.location = location - self.children = children - self.tags = tags - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentContentChangeEvent.swift b/Sources/LanguageServerProtocol/SupportTypes/TextDocumentContentChangeEvent.swift deleted file mode 100644 index aa28c3c86..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentContentChangeEvent.swift +++ /dev/null @@ -1,32 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A change to a text document. -/// -/// If `range` and `rangeLength` are unspecified, the whole document content is replaced. -/// -/// The `range.end` and `rangeLength` are potentially redundant. Based on https://github.com/Microsoft/language-server-protocol/issues/9, servers should be lenient and accept either. -public struct TextDocumentContentChangeEvent: Codable, Hashable, Sendable { - - @CustomCodable - public var range: Range? - - public var rangeLength: Int? - - public var text: String - - public init(range: Range? = nil, rangeLength: Int? = nil, text: String) { - self._range = CustomCodable(wrappedValue: range) - self.rangeLength = rangeLength - self.text = text - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentEdit.swift b/Sources/LanguageServerProtocol/SupportTypes/TextDocumentEdit.swift deleted file mode 100644 index 60f801151..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentEdit.swift +++ /dev/null @@ -1,55 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Edit within a particular document. -/// -/// For an edit where the document is implied, use `TextEdit`. -public struct TextDocumentEdit: Hashable, Codable, Sendable { - public enum Edit: Codable, Hashable, Sendable { - case textEdit(TextEdit) - case annotatedTextEdit(AnnotatedTextEdit) - - public init(from decoder: Decoder) throws { - if let annotated = try? AnnotatedTextEdit(from: decoder) { - self = .annotatedTextEdit(annotated) - } else if let edit = try? TextEdit(from: decoder) { - self = .textEdit(edit) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected AnnotatedTextEdit or TextEdit" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .textEdit(let edit): - try edit.encode(to: encoder) - case .annotatedTextEdit(let annotated): - try annotated.encode(to: encoder) - } - } - } - - /// The potentially versioned document to which these edits apply. - public var textDocument: OptionalVersionedTextDocumentIdentifier - - /// The edits to be applied, which must be non-overlapping. - public var edits: [Edit] - - public init(textDocument: OptionalVersionedTextDocumentIdentifier, edits: [Edit]) { - self.textDocument = textDocument - self.edits = edits - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentIdentifier.swift b/Sources/LanguageServerProtocol/SupportTypes/TextDocumentIdentifier.swift deleted file mode 100644 index 6f4a713d8..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentIdentifier.swift +++ /dev/null @@ -1,40 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Unique identifier for a document. -public struct TextDocumentIdentifier: Hashable, Codable, Sendable { - - /// A URI that uniquely identifies the document. - public var uri: DocumentURI - - public init(_ uri: DocumentURI) { - self.uri = uri - } -} - -extension TextDocumentIdentifier: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard case .string(let uriString)? = dictionary[CodingKeys.uri.stringValue] else { - return nil - } - guard let uri = try? DocumentURI(string: uriString) else { - return nil - } - self.uri = uri - } - - public func encodeToLSPAny() -> LSPAny { - return .dictionary([ - CodingKeys.uri.stringValue: .string(uri.stringValue) - ]) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentItem.swift b/Sources/LanguageServerProtocol/SupportTypes/TextDocumentItem.swift deleted file mode 100644 index 2bb436612..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentItem.swift +++ /dev/null @@ -1,41 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The content and metadata of a text document. -public struct TextDocumentItem: Hashable, Sendable { - - public var uri: DocumentURI - - public var language: Language - - /// The version number of this document, which increases after each edit. - public var version: Int - - /// The content of the document. - public var text: String - - public init(uri: DocumentURI, language: Language, version: Int, text: String) { - self.uri = uri - self.language = language - self.version = version - self.text = text - } -} - -extension TextDocumentItem: Codable { - private enum CodingKeys: String, CodingKey { - case uri - case language = "languageId" - case version - case text - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentSaveReason.swift b/Sources/LanguageServerProtocol/SupportTypes/TextDocumentSaveReason.swift deleted file mode 100644 index 23b864893..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextDocumentSaveReason.swift +++ /dev/null @@ -1,22 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum TextDocumentSaveReason: Int, Codable, Hashable, Sendable { - - case manual = 1 - - /// Automatic save after a delay. - case afterDelay = 2 - - /// Automatic save after the editor loses focus. - case focusOut = 3 -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TextEdit.swift b/Sources/LanguageServerProtocol/SupportTypes/TextEdit.swift deleted file mode 100644 index f4fe5c6c8..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TextEdit.swift +++ /dev/null @@ -1,95 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Edit to a text document, replacing the contents of `range` with `text`. -public struct TextEdit: ResponseType, Hashable, Sendable { - - /// The range of text to be replaced. - @CustomCodable - public var range: Range - - /// The new text. - public var newText: String - - public init(range: Range, newText: String) { - self._range = CustomCodable(wrappedValue: range) - self.newText = newText - } -} - -extension TextEdit: LSPAnyCodable { - public init?(fromLSPDictionary dictionary: [String: LSPAny]) { - guard case .dictionary(let rangeDict) = dictionary[CodingKeys.range.stringValue], - case .string(let newText) = dictionary[CodingKeys.newText.stringValue] - else { - return nil - } - guard let range = Range(fromLSPDictionary: rangeDict) else { - return nil - } - self._range = CustomCodable(wrappedValue: range) - self.newText = newText - } - - public func encodeToLSPAny() -> LSPAny { - return .dictionary([ - CodingKeys.range.stringValue: range.encodeToLSPAny(), - CodingKeys.newText.stringValue: .string(newText), - ]) - } -} - -/// Additional information that describes document changes. -public struct ChangeAnnotation: Codable, Hashable, Sendable { - /// A human-readable string describing the actual change. The string - /// is rendered prominent in the user interface. - public var label: String - - /// A flag which indicates that user confirmation is needed - /// before applying the change. - public var needsConfirmation: Bool? = nil - - /// A human-readable string which is rendered less prominent in - /// the user interface. - public var description: String? = nil - - public init(label: String, needsConfirmation: Bool? = nil, description: String? = nil) { - self.label = label - self.needsConfirmation = needsConfirmation - self.description = description - } -} - -/// An identifier referring to a change annotation managed by a workspace -/// edit. -public typealias ChangeAnnotationIdentifier = String - -/// A special text edit with an additional change annotation. -/// -/// Notionally a subtype of `TextEdit`. -public struct AnnotatedTextEdit: ResponseType, Hashable, Sendable { - - /// The range of text to be replaced. - @CustomCodable - public var range: Range - - /// The new text. - public var newText: String - - public var annotationId: ChangeAnnotationIdentifier - - public init(range: Range, newText: String, annotationId: ChangeAnnotationIdentifier) { - self._range = CustomCodable(wrappedValue: range) - self.newText = newText - self.annotationId = annotationId - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/Tracing.swift b/Sources/LanguageServerProtocol/SupportTypes/Tracing.swift deleted file mode 100644 index d008578d2..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/Tracing.swift +++ /dev/null @@ -1,17 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public enum Tracing: String, Codable, Sendable { - case off - case messages - case verbose -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/TypeHierarchyItem.swift b/Sources/LanguageServerProtocol/SupportTypes/TypeHierarchyItem.swift deleted file mode 100644 index 280641f2c..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/TypeHierarchyItem.swift +++ /dev/null @@ -1,58 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A single type hierarchy item. -public struct TypeHierarchyItem: ResponseType, Hashable, Sendable { - /// Name of this item. - public var name: String - /// The kind of this item. - public var kind: SymbolKind - /// Tags for this item - public var tags: [SymbolTag]? - /// More detail for this item. - public var detail: String? - - /// The resource identifier of this item. - public var uri: DocumentURI - - /// The range enclosing this symbol not including leading/trailing whitespace - /// but everything else, e.g. comments and code. - @CustomCodable - public var range: Range - /// The range that should be selected and revealed when this symbol is being picked. - @CustomCodable - public var selectionRange: Range - - /// A data entry field that is preserved between a type hierarchy prepare and - /// subtype/supertype requests. - public var data: LSPAny? - - public init( - name: String, - kind: SymbolKind, - tags: [SymbolTag]?, - detail: String? = nil, - uri: DocumentURI, - range: Range, - selectionRange: Range, - data: LSPAny? = nil - ) { - self.name = name - self.kind = kind - self.tags = tags - self.detail = detail - self.uri = uri - self.range = range - self.selectionRange = selectionRange - self.data = data - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/VersionedNotebookDocumentIdentifier.swift b/Sources/LanguageServerProtocol/SupportTypes/VersionedNotebookDocumentIdentifier.swift deleted file mode 100644 index 2b4edf181..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/VersionedNotebookDocumentIdentifier.swift +++ /dev/null @@ -1,26 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Unique identifier for a document. -public struct VersionedNotebookDocumentIdentifier: Codable, Hashable, Sendable { - - /// The version number of this notebook document. - public var version: Int - - /// The notebook document's URI. - public var uri: DocumentURI - - public init(version: Int, uri: DocumentURI) { - self.version = version - self.uri = uri - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/VersionedTextDocumentIdentifier.swift b/Sources/LanguageServerProtocol/SupportTypes/VersionedTextDocumentIdentifier.swift deleted file mode 100644 index 320bac974..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/VersionedTextDocumentIdentifier.swift +++ /dev/null @@ -1,70 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A document identifier representing a specific version of the document. -/// -/// Notionally a subtype of `TextDocumentIdentifier`. -public struct VersionedTextDocumentIdentifier: Hashable, Codable, Sendable { - - /// A URI that uniquely identifies the document. - public var uri: DocumentURI - - /// The version number of this document. - /// - /// The version number of a document will increase after each change, - /// including undo/redo. The number doesn't need to be consecutive. - public var version: Int - - public init(_ uri: DocumentURI, version: Int) { - self.uri = uri - self.version = version - } -} - -/// An identifier which optionally denotes a specific version of a text document. This information usually flows from the server to the client. -/// -/// Notionally a subtype of `TextDocumentIdentifier`. -public struct OptionalVersionedTextDocumentIdentifier: Hashable, Codable, Sendable { - - /// A URI that uniquely identifies the document. - public var uri: DocumentURI - - /// The version number of this document. If an optional versioned text document - /// identifier is sent from the server to the client and the file is not - /// open in the editor (the server has not received an open notification - /// before) the server can send `null` to indicate that the version is - /// known and the content on disk is the primary (as specified with document - /// content ownership). - /// - /// The version number of a document will increase after each change, - /// including undo/redo. The number doesn't need to be consecutive. - public var version: Int? - - public init(_ uri: DocumentURI, version: Int?) { - self.uri = uri - self.version = version - } - - enum CodingKeys: CodingKey { - case uri - case version - } - - public func encode(to encoder: any Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(self.uri, forKey: .uri) - - // Note: we use encode(_:forKey:) here instead of encodeIf(_:forKey:) - // because VSCode will drop requests without the explicit 'null'. - try container.encode(self.version, forKey: .version) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/WindowMessageType.swift b/Sources/LanguageServerProtocol/SupportTypes/WindowMessageType.swift deleted file mode 100644 index e3ae78cee..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/WindowMessageType.swift +++ /dev/null @@ -1,20 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The type of message (error, etc.) for a ShowMessage or LogMessage request. Corresponds to `MessageType` in LSP. -public enum WindowMessageType: Int, Codable, Hashable, Sendable { - - case error = 1 - case warning = 2 - case info = 3 - case log = 4 -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceEdit.swift b/Sources/LanguageServerProtocol/SupportTypes/WorkspaceEdit.swift deleted file mode 100644 index 9e2793068..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceEdit.swift +++ /dev/null @@ -1,305 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// A workspace edit represents changes to many resources managed in the workspace. -public struct WorkspaceEdit: Hashable, ResponseType, Sendable { - - /// The edits to be applied to existing resources. - public var changes: [DocumentURI: [TextEdit]]? - - public var documentChanges: [WorkspaceEditDocumentChange]? - - /// A map of change annotations that can be referenced in - /// `AnnotatedTextEdit`s or create, rename and delete file / folder - /// operations. - /// - /// Whether clients honor this property depends on the client capability - /// `workspace.changeAnnotationSupport`. - public var changeAnnotations: [ChangeAnnotationIdentifier: ChangeAnnotation]? - - public init( - changes: [DocumentURI: [TextEdit]]? = nil, - documentChanges: [WorkspaceEditDocumentChange]? = nil, - changeAnnotation: [ChangeAnnotationIdentifier: ChangeAnnotation]? = nil - ) { - self.changes = changes - self.documentChanges = documentChanges - self.changeAnnotations = changeAnnotation - } -} - -// Workaround for Codable not correctly encoding dictionaries whose keys aren't strings. -extension WorkspaceEdit: Codable { - private enum CodingKeys: String, CodingKey { - case changes - case documentChanges - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - if let changesDict = try container.decodeIfPresent([String: [TextEdit]].self, forKey: .changes) { - var changes = [DocumentURI: [TextEdit]]() - for change in changesDict { - let uri = try DocumentURI(string: change.key) - changes[uri] = change.value - } - self.changes = changes - } else { - self.changes = nil - } - self.documentChanges = try container.decodeIfPresent([WorkspaceEditDocumentChange].self, forKey: .documentChanges) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - if let changes = changes { - var stringDictionary = [String: [TextEdit]]() - for (key, value) in changes { - stringDictionary[key.stringValue] = value - } - try container.encodeIfPresent(stringDictionary, forKey: .changes) - } - try container.encodeIfPresent(documentChanges, forKey: .documentChanges) - } -} - -public enum WorkspaceEditDocumentChange: Codable, Hashable, Sendable { - case textDocumentEdit(TextDocumentEdit) - case createFile(CreateFile) - case renameFile(RenameFile) - case deleteFile(DeleteFile) - - public init(from decoder: Decoder) throws { - if let edit = try? TextDocumentEdit(from: decoder) { - self = .textDocumentEdit(edit) - } else if let createFile = try? CreateFile(from: decoder) { - self = .createFile(createFile) - } else if let renameFile = try? RenameFile(from: decoder) { - self = .renameFile(renameFile) - } else if let deleteFile = try? DeleteFile(from: decoder) { - self = .deleteFile(deleteFile) - } else { - let context = DecodingError.Context( - codingPath: decoder.codingPath, - debugDescription: "Expected TextDocumentEdit, CreateFile, RenameFile, or DeleteFile" - ) - throw DecodingError.dataCorrupted(context) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .textDocumentEdit(let textDocumentEdit): - try textDocumentEdit.encode(to: encoder) - case .createFile(let createFile): - try createFile.encode(to: encoder) - case .renameFile(let renameFile): - try renameFile.encode(to: encoder) - case .deleteFile(let deleteFile): - try deleteFile.encode(to: encoder) - } - } -} - -/// Options to create a file. -public struct CreateFileOptions: Codable, Hashable, Sendable { - /// Overwrite existing file. Overwrite wins over `ignoreIfExists` - public var overwrite: Bool? - /// Ignore if exists. - public var ignoreIfExists: Bool? - - public init(overwrite: Bool? = nil, ignoreIfExists: Bool? = nil) { - self.overwrite = overwrite - self.ignoreIfExists = ignoreIfExists - } -} - -/// Create file operation -public struct CreateFile: Codable, Hashable, Sendable { - /// The resource to create. - public var uri: DocumentURI - /// Additional options - public var options: CreateFileOptions? - /// An optional annotation identifier describing the operation. - public var annotationId: ChangeAnnotationIdentifier? - - public init(uri: DocumentURI, options: CreateFileOptions? = nil, annotationId: ChangeAnnotationIdentifier? = nil) { - self.uri = uri - self.options = options - self.annotationId = annotationId - } - - // MARK: Codable conformance - - public enum CodingKeys: String, CodingKey { - case kind - case uri - case options - case annotationId - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "create" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of CreateFile is not 'create'" - ) - } - self.uri = try container.decode(DocumentURI.self, forKey: .uri) - self.options = try container.decodeIfPresent(CreateFileOptions.self, forKey: .options) - self.annotationId = try container.decodeIfPresent(ChangeAnnotationIdentifier.self, forKey: .annotationId) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("create", forKey: .kind) - try container.encode(self.uri, forKey: .uri) - try container.encodeIfPresent(self.options, forKey: .options) - try container.encodeIfPresent(self.annotationId, forKey: .annotationId) - } -} - -/// Rename file options -public struct RenameFileOptions: Codable, Hashable, Sendable { - /// Overwrite target if existing. Overwrite wins over `ignoreIfExists` - public var overwrite: Bool? - /// Ignores if target exists. - public var ignoreIfExists: Bool? - - public init(overwrite: Bool? = nil, ignoreIfExists: Bool? = nil) { - self.overwrite = overwrite - self.ignoreIfExists = ignoreIfExists - } -} - -/// Rename file operation -public struct RenameFile: Codable, Hashable, Sendable { - /// The old (existing) location. - public var oldUri: DocumentURI - /// The new location. - public var newUri: DocumentURI - /// Rename options. - public var options: RenameFileOptions? - /// An optional annotation identifier describing the operation. - public var annotationId: ChangeAnnotationIdentifier? - - public init( - oldUri: DocumentURI, - newUri: DocumentURI, - options: RenameFileOptions? = nil, - annotationId: ChangeAnnotationIdentifier? = nil - ) { - self.oldUri = oldUri - self.newUri = newUri - self.options = options - self.annotationId = annotationId - } - - // MARK: Codable conformance - - public enum CodingKeys: String, CodingKey { - case kind - case oldUri - case newUri - case options - case annotationId - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "rename" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of RenameFile is not 'rename'" - ) - } - self.oldUri = try container.decode(DocumentURI.self, forKey: .oldUri) - self.newUri = try container.decode(DocumentURI.self, forKey: .newUri) - self.options = try container.decodeIfPresent(RenameFileOptions.self, forKey: .options) - self.annotationId = try container.decodeIfPresent(ChangeAnnotationIdentifier.self, forKey: .annotationId) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("rename", forKey: .kind) - try container.encode(self.oldUri, forKey: .oldUri) - try container.encode(self.newUri, forKey: .newUri) - try container.encodeIfPresent(self.options, forKey: .options) - try container.encodeIfPresent(self.annotationId, forKey: .annotationId) - } -} - -/// Delete file options -public struct DeleteFileOptions: Codable, Hashable, Sendable { - /// Delete the content recursively if a folder is denoted. - public var recursive: Bool? - /// Ignore the operation if the file doesn't exist. - public var ignoreIfNotExists: Bool? - - public init(recursive: Bool? = nil, ignoreIfNotExists: Bool? = nil) { - self.recursive = recursive - self.ignoreIfNotExists = ignoreIfNotExists - } -} - -/// Delete file operation -public struct DeleteFile: Codable, Hashable, Sendable { - /// The file to delete. - public var uri: DocumentURI - /// Delete options. - public var options: DeleteFileOptions? - /// An optional annotation identifier describing the operation. - public var annotationId: ChangeAnnotationIdentifier? - - public init(uri: DocumentURI, options: DeleteFileOptions? = nil, annotationId: ChangeAnnotationIdentifier? = nil) { - self.uri = uri - self.options = options - self.annotationId = annotationId - } - - // MARK: Codable conformance - - public enum CodingKeys: String, CodingKey { - case kind - case uri - case options - case annotationId - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let kind = try container.decode(String.self, forKey: .kind) - guard kind == "delete" else { - throw DecodingError.dataCorruptedError( - forKey: .kind, - in: container, - debugDescription: "Kind of DeleteFile is not 'delete'" - ) - } - self.uri = try container.decode(DocumentURI.self, forKey: .uri) - self.options = try container.decodeIfPresent(DeleteFileOptions.self, forKey: .options) - self.annotationId = try container.decodeIfPresent(ChangeAnnotationIdentifier.self, forKey: .annotationId) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("delete", forKey: .kind) - try container.encode(self.uri, forKey: .uri) - try container.encodeIfPresent(self.options, forKey: .options) - try container.encodeIfPresent(self.annotationId, forKey: .annotationId) - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceFolder.swift b/Sources/LanguageServerProtocol/SupportTypes/WorkspaceFolder.swift deleted file mode 100644 index 110befc1d..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceFolder.swift +++ /dev/null @@ -1,33 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// Unique identifier for a document. -public struct WorkspaceFolder: ResponseType, Hashable, Codable, Sendable { - - /// A URI that uniquely identifies the workspace. - public var uri: DocumentURI - - /// The name of the workspace (default: basename of url). - public var name: String - - public init(uri: DocumentURI, name: String? = nil) { - self.uri = uri - - self.name = name ?? uri.fileURL?.lastPathComponent ?? "unknown_workspace" - - if self.name.isEmpty { - self.name = "unknown_workspace" - } - } -} diff --git a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceSettings.swift b/Sources/LanguageServerProtocol/SupportTypes/WorkspaceSettings.swift deleted file mode 100644 index 2f10218c6..000000000 --- a/Sources/LanguageServerProtocol/SupportTypes/WorkspaceSettings.swift +++ /dev/null @@ -1,81 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// The `settings` field of a `workspace/didChangeConfiguration`. -/// -/// This is typed as `Any` in the protocol, and this enum contains the formats we support. -public enum WorkspaceSettingsChange: Codable, Hashable, Sendable { - - case clangd(ClangWorkspaceSettings) - case unknown(LSPAny) - - public init(from decoder: Decoder) throws { - if let settings = try? ClangWorkspaceSettings(from: decoder), settings.isValid { - self = .clangd(settings) - } else { - let settings = try LSPAny(from: decoder) - self = .unknown(settings) - } - } - - public func encode(to encoder: Encoder) throws { - switch self { - case .clangd(let settings): - try settings.encode(to: encoder) - case .unknown(let settings): - try settings.encode(to: encoder) - } - } -} - -/// Workspace settings for clangd, represented by a compilation database. -/// -/// Clangd will accept *either* a path to a compilation database on disk, or the contents of a -/// compilation database to be managed in-memory, but they cannot be mixed. -public struct ClangWorkspaceSettings: Codable, Hashable, Sendable { - - /// The path to a json compilation database. - public var compilationDatabasePath: String? - - /// Mapping from file name to compilation command. - public var compilationDatabaseChanges: [String: ClangCompileCommand]? - - public init( - compilationDatabasePath: String? = nil, - compilationDatabaseChanges: [String: ClangCompileCommand]? = nil - ) { - self.compilationDatabasePath = compilationDatabasePath - self.compilationDatabaseChanges = compilationDatabaseChanges - } - - var isValid: Bool { - switch (compilationDatabasePath, compilationDatabaseChanges) { - case (nil, .some), (.some, nil): return true - default: return false - } - } -} - -/// A single compile command for use in a clangd workspace settings. -public struct ClangCompileCommand: Codable, Hashable, Sendable { - - /// The command (executable + compiler arguments). - public var compilationCommand: [String] - - /// The directory to perform the compilation in. - public var workingDirectory: String - - public init(compilationCommand: [String], workingDirectory: String) { - self.compilationCommand = compilationCommand - self.workingDirectory = workingDirectory - } -} diff --git a/Sources/LanguageServerProtocolExtensions/CMakeLists.txt b/Sources/LanguageServerProtocolExtensions/CMakeLists.txt index 34d50f9db..6a488b5d0 100644 --- a/Sources/LanguageServerProtocolExtensions/CMakeLists.txt +++ b/Sources/LanguageServerProtocolExtensions/CMakeLists.txt @@ -1,12 +1,8 @@ add_library(LanguageServerProtocolExtensions STATIC Connection+Send.swift - DocumentURI+CustomLogStringConvertible.swift DocumentURI+symlinkTarget.swift Language+Inference.swift - LocalConnection.swift - QueueBasedMessageHandler.swift - RequestAndReply.swift ResponseError+Init.swift WorkDoneProgressManager.swift ) @@ -15,9 +11,10 @@ set_target_properties(LanguageServerProtocolExtensions PROPERTIES target_link_libraries(LanguageServerProtocolExtensions PUBLIC SourceKitD) target_link_libraries(LanguageServerProtocolExtensions PRIVATE - LanguageServerProtocol - LanguageServerProtocolJSONRPC - SKLogging + SwiftToolsProtocols::LanguageServerProtocol + SwiftToolsProtocols::LanguageServerProtocolTransport + SwiftToolsProtocols::SKLogging SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions TSCBasic $<$>:Foundation>) diff --git a/Sources/LanguageServerProtocolExtensions/Connection+Send.swift b/Sources/LanguageServerProtocolExtensions/Connection+Send.swift index 235e506e2..1fee33fee 100644 --- a/Sources/LanguageServerProtocolExtensions/Connection+Send.swift +++ b/Sources/LanguageServerProtocolExtensions/Connection+Send.swift @@ -10,8 +10,9 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions extension Connection { /// Send the given request to the connection and await its result. diff --git a/Sources/LanguageServerProtocolExtensions/DocumentURI+CustomLogStringConvertible.swift b/Sources/LanguageServerProtocolExtensions/DocumentURI+CustomLogStringConvertible.swift deleted file mode 100644 index 4243812d8..000000000 --- a/Sources/LanguageServerProtocolExtensions/DocumentURI+CustomLogStringConvertible.swift +++ /dev/null @@ -1,24 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -import LanguageServerProtocol -import SKLogging - -// MARK: - DocumentURI - -extension DocumentURI { - package var redactedDescription: String { - return "" - } -} -extension DocumentURI: SKLogging.CustomLogStringConvertible {} diff --git a/Sources/LanguageServerProtocolExtensions/DocumentURI+symlinkTarget.swift b/Sources/LanguageServerProtocolExtensions/DocumentURI+symlinkTarget.swift index a8dfa10cf..acf9838a8 100644 --- a/Sources/LanguageServerProtocolExtensions/DocumentURI+symlinkTarget.swift +++ b/Sources/LanguageServerProtocolExtensions/DocumentURI+symlinkTarget.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SwiftExtensions extension DocumentURI { diff --git a/Sources/LanguageServerProtocolExtensions/Language+Inference.swift b/Sources/LanguageServerProtocolExtensions/Language+Inference.swift index 489ed5ee7..c9d7a431d 100644 --- a/Sources/LanguageServerProtocolExtensions/Language+Inference.swift +++ b/Sources/LanguageServerProtocolExtensions/Language+Inference.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol extension Language { package enum SemanticKind { diff --git a/Sources/LanguageServerProtocolExtensions/LocalConnection.swift b/Sources/LanguageServerProtocolExtensions/LocalConnection.swift deleted file mode 100644 index 0c766bd2f..000000000 --- a/Sources/LanguageServerProtocolExtensions/LocalConnection.swift +++ /dev/null @@ -1,155 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Dispatch -import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolJSONRPC -import SKLogging -import SwiftExtensions - -/// A connection between two message handlers in the same process. -/// -/// You must call `start(handler:)` before sending any messages, and must call `close()` when finished to avoid a memory leak. -/// -/// ``` -/// let client: MessageHandler = ... -/// let server: MessageHandler = ... -/// let conn = LocalConnection() -/// conn.start(handler: server) -/// conn.send(...) // handled by server -/// conn.close() -/// ``` -package final class LocalConnection: Connection, Sendable { - private enum State { - case ready, started, closed - } - - /// A name of the endpoint for this connection, used for logging, e.g. `clangd`. - private let name: String - - /// The queue guarding `_nextRequestID`. - private let queue: DispatchQueue = DispatchQueue(label: "local-connection-queue") - - private let _nextRequestID = AtomicUInt32(initialValue: 0) - - /// - Important: Must only be accessed from `queue` - nonisolated(unsafe) private var state: State = .ready - - /// - Important: Must only be accessed from `queue` - nonisolated(unsafe) private var handler: MessageHandler? = nil - - package init(receiverName: String) { - self.name = receiverName - } - - package convenience init(receiverName: String, handler: MessageHandler) { - self.init(receiverName: receiverName) - self.start(handler: handler) - } - - deinit { - queue.sync { - if state != .closed { - closeAssumingOnQueue() - } - } - } - - package func start(handler: MessageHandler) { - queue.sync { - precondition(state == .ready) - state = .started - self.handler = handler - } - } - - /// - Important: Must only be called from `queue` - private func closeAssumingOnQueue() { - dispatchPrecondition(condition: .onQueue(queue)) - precondition(state != .closed) - handler = nil - state = .closed - } - - package func close() { - queue.sync { - closeAssumingOnQueue() - } - } - - public func nextRequestID() -> RequestID { - return .string("sk-\(_nextRequestID.fetchAndIncrement())") - } - - package func send(_ notification: Notification) { - logger.info( - """ - Sending notification to \(self.name, privacy: .public) - \(notification.forLogging) - """ - ) - guard let handler = queue.sync(execute: { handler }) else { - return - } - handler.handle(notification) - } - - package func send( - _ request: Request, - id: RequestID, - reply: @Sendable @escaping (LSPResult) -> Void - ) { - logger.info( - """ - Sending request to \(self.name, privacy: .public) (id: \(id, privacy: .public)): - \(request.forLogging) - """ - ) - - guard let handler = queue.sync(execute: { handler }) else { - logger.info( - """ - Replying to request \(id, privacy: .public) with .serverCancelled because no handler is specified in \(self.name, privacy: .public) - """ - ) - reply(.failure(.serverCancelled)) - return - } - - precondition(self.state == .started) - let startDate = Date() - handler.handle(request, id: id) { result in - switch result { - case .success(let response): - logger.info( - """ - Received reply for request \(id, privacy: .public) from \(self.name, privacy: .public) \ - (took \(Date().timeIntervalSince(startDate) * 1000, privacy: .public)ms) - \(Request.method, privacy: .public) - \(response.forLogging) - """ - ) - case .failure(let error): - logger.error( - """ - Received error for request \(id, privacy: .public) from \(self.name, privacy: .public) \ - (took \(Date().timeIntervalSince(startDate) * 1000, privacy: .public)ms) - \(Request.method, privacy: .public) - \(error.forLogging) - """ - ) - } - reply(result) - } - } -} diff --git a/Sources/LanguageServerProtocolExtensions/QueueBasedMessageHandler.swift b/Sources/LanguageServerProtocolExtensions/QueueBasedMessageHandler.swift deleted file mode 100644 index 7fc5bc14c..000000000 --- a/Sources/LanguageServerProtocolExtensions/QueueBasedMessageHandler.swift +++ /dev/null @@ -1,246 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolJSONRPC -import SKLogging -package import SwiftExtensions - -/// Side structure in which `QueueBasedMessageHandler` can keep track of active requests etc. -/// -/// All of these could be requirements on `QueueBasedMessageHandler` but having them in a separate type means that -/// types conforming to `QueueBasedMessageHandler` only have to have a single member and it also ensures that these -/// fields are not accessible outside of the implementation of `QueueBasedMessageHandler`. -package actor QueueBasedMessageHandlerHelper { - /// The category in which signposts for message handling should be logged. - fileprivate let signpostLoggingCategory: String - - /// Whether a new logging scope should be created when handling a notification / request. - private let createLoggingScope: Bool - - /// The queue on which we start and stop keeping track of cancellation. - /// - /// Having a queue for this ensures that we started keeping track of a - /// request's task before handling any cancellation request for it. - private let cancellationMessageHandlingQueue = AsyncQueue() - - /// Notifications don't have an ID. This represents the next ID we can use to identify a notification. - private let notificationIDForLogging = AtomicUInt32(initialValue: 1) - - /// The requests that we are currently handling. - /// - /// Used to cancel the tasks if the client requests cancellation. - private var inProgressRequestsByID: [RequestID: Task<(), Never>] = [:] - - /// Up to 10 request IDs that have recently finished. - /// - /// This is only used so we don't log an error when receiving a `CancelRequestNotification` for a request that has - /// just returned a response. - private var recentlyFinishedRequests: [RequestID] = [] - - package init(signpostLoggingCategory: String, createLoggingScope: Bool) { - self.signpostLoggingCategory = signpostLoggingCategory - self.createLoggingScope = createLoggingScope - } - - /// Cancel the request with the given ID. - /// - /// Cancellation is performed automatically when a `$/cancelRequest` notification is received. This can be called to - /// implicitly cancel requests based on some criteria. - package nonisolated func cancelRequest(id: RequestID) { - // Since the request is very cheap to execute and stops other requests - // from performing more work, we execute it with a high priority. - cancellationMessageHandlingQueue.async(priority: .high) { - if let task = await self.inProgressRequestsByID[id] { - task.cancel() - return - } - if await !self.recentlyFinishedRequests.contains(id) { - logger.error( - "Cannot cancel request \(id, privacy: .public) because it hasn't been scheduled for execution yet" - ) - } - } - } - - fileprivate nonisolated func setInProgressRequest(id: RequestID, request: some RequestType, task: Task<(), Never>?) { - self.cancellationMessageHandlingQueue.async(priority: .background) { - await self.setInProgressRequestImpl(id: id, request: request, task: task) - } - } - - private func setInProgressRequestImpl(id: RequestID, request: some RequestType, task: Task<(), Never>?) { - self.inProgressRequestsByID[id] = task - if task == nil { - self.recentlyFinishedRequests.append(id) - while self.recentlyFinishedRequests.count > 10 { - self.recentlyFinishedRequests.removeFirst() - } - } - } - - fileprivate nonisolated func withNotificationLoggingScopeIfNecessary(_ body: () -> Void) { - guard createLoggingScope else { - body() - return - } - // Only use the last two digits of the notification ID for the logging scope to avoid creating too many scopes. - // See comment in `withLoggingScope`. - // The last 2 digits should be sufficient to differentiate between multiple concurrently running notifications. - let notificationID = notificationIDForLogging.fetchAndIncrement() - withLoggingScope("notification-\(notificationID % 100)") { - body() - } - } - - fileprivate nonisolated func withRequestLoggingScopeIfNecessary( - id: RequestID, - _ body: @Sendable () async -> Void - ) async { - guard createLoggingScope else { - await body() - return - } - // Only use the last two digits of the request ID for the logging scope to avoid creating too many scopes. - // See comment in `withLoggingScope`. - // The last 2 digits should be sufficient to differentiate between multiple concurrently running requests. - await withLoggingScope("request-\(id.numericValue % 100)") { - await body() - } - } -} - -package protocol QueueBasedMessageHandlerDependencyTracker: DependencyTracker { - init(_ notification: some NotificationType) - init(_ request: some RequestType) -} - -/// A `MessageHandler` that handles all messages on an `AsyncQueue` and tracks dependencies between requests using -/// `DependencyTracker`, ensuring that requests which depend on each other are not executed out-of-order. -package protocol QueueBasedMessageHandler: MessageHandler { - associatedtype DependencyTracker: QueueBasedMessageHandlerDependencyTracker - - /// The queue on which all messages (notifications, requests, responses) are - /// handled. - /// - /// The queue is blocked until the message has been sufficiently handled to - /// avoid out-of-order handling of messages. For sourcekitd, this means that - /// a request has been sent to sourcekitd and for clangd, this means that we - /// have forwarded the request to clangd. - /// - /// The actual semantic handling of the message happens off this queue. - var messageHandlingQueue: AsyncQueue { get } - - var messageHandlingHelper: QueueBasedMessageHandlerHelper { get } - - /// Called when a notification has been received but before it is being handled in `messageHandlingQueue`. - /// - /// Adopters can use this to implicitly cancel requests when a notification is received. - func didReceive(notification: some NotificationType) - - /// Called when a request has been received but before it is being handled in `messageHandlingQueue`. - /// - /// Adopters can use this to implicitly cancel requests when a notification is received. - func didReceive(request: some RequestType, id: RequestID) - - /// Perform the actual handling of `notification`. - func handle(notification: some NotificationType) async - - /// Perform the actual handling of `request`. - func handle( - request: Request, - id: RequestID, - reply: @Sendable @escaping (LSPResult) -> Void - ) async -} - -extension QueueBasedMessageHandler { - package func didReceive(notification: some NotificationType) {} - package func didReceive(request: some RequestType, id: RequestID) {} - - package func handle(_ notification: some NotificationType) { - messageHandlingHelper.withNotificationLoggingScopeIfNecessary { - // Request cancellation needs to be able to overtake any other message we - // are currently handling. Ordering is not important here. We thus don't - // need to execute it on `messageHandlingQueue`. - if let notification = notification as? CancelRequestNotification { - logger.log("Received cancel request notification: \(notification.forLogging)") - self.messageHandlingHelper.cancelRequest(id: notification.id) - return - } - self.didReceive(notification: notification) - - let signposter = Logger( - subsystem: LoggingScope.subsystem, - category: messageHandlingHelper.signpostLoggingCategory - ) - .makeSignposter() - let signpostID = signposter.makeSignpostID() - let state = signposter.beginInterval( - "Notification", - id: signpostID, - "\(type(of: notification).method, privacy: .public)" - ) - messageHandlingQueue.async(metadata: DependencyTracker(notification)) { - signposter.emitEvent("Start handling", id: signpostID) - await self.handle(notification: notification) - signposter.endInterval("Notification", state, "Done") - } - } - } - - package func handle( - _ request: Request, - id: RequestID, - reply: @Sendable @escaping (LSPResult) -> Void - ) { - let signposter = Logger(subsystem: LoggingScope.subsystem, category: messageHandlingHelper.signpostLoggingCategory) - .makeSignposter() - let signpostID = signposter.makeSignpostID() - let state = signposter.beginInterval("Request", id: signpostID, "\(Request.method, privacy: .public)") - - self.didReceive(request: request, id: id) - - let task = messageHandlingQueue.async(metadata: DependencyTracker(request)) { - signposter.emitEvent("Start handling", id: signpostID) - await self.messageHandlingHelper.withRequestLoggingScopeIfNecessary(id: id) { - await withTaskCancellationHandler { - await self.handle(request: request, id: id, reply: reply) - signposter.endInterval("Request", state, "Done") - } onCancel: { - signposter.emitEvent("Cancelled", id: signpostID) - } - } - // We have handled the request and can't cancel it anymore. - // Stop keeping track of it to free the memory. - self.messageHandlingHelper.setInProgressRequest(id: id, request: request, task: nil) - } - // Keep track of the ID -> Task management with low priority. Once we cancel - // a request, the cancellation task runs with a high priority and depends on - // this task, which will elevate this task's priority. - self.messageHandlingHelper.setInProgressRequest(id: id, request: request, task: task) - } -} - -fileprivate extension RequestID { - /// Returns a numeric value for this request ID. - /// - /// For request IDs that are numbers, this is straightforward. For string-based request IDs, this uses a hash to - /// convert the string into a number. - var numericValue: Int { - switch self { - case .number(let number): return number - case .string(let string): return Int(string) ?? abs(string.hashValue) - } - } -} diff --git a/Sources/LanguageServerProtocolExtensions/RequestAndReply.swift b/Sources/LanguageServerProtocolExtensions/RequestAndReply.swift deleted file mode 100644 index 8140f6531..000000000 --- a/Sources/LanguageServerProtocolExtensions/RequestAndReply.swift +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -package import LanguageServerProtocol -import SwiftExtensions - -/// A request and a callback that returns the request's reply -package final class RequestAndReply: Sendable { - package let params: Params - private let replyBlock: @Sendable (LSPResult) -> Void - - /// Whether a reply has been made. Every request must reply exactly once. - private let replied: AtomicBool = AtomicBool(initialValue: false) - - package init(_ request: Params, reply: @escaping @Sendable (LSPResult) -> Void) { - self.params = request - self.replyBlock = reply - } - - deinit { - precondition(replied.value, "request never received a reply") - } - - /// Call the `replyBlock` with the result produced by the given closure. - package func reply(_ body: @Sendable () async throws -> Params.Response) async { - precondition(!replied.value, "replied to request more than once") - replied.value = true - do { - replyBlock(.success(try await body())) - } catch { - replyBlock(.failure(ResponseError(error))) - } - } -} diff --git a/Sources/LanguageServerProtocolExtensions/ResponseError+Init.swift b/Sources/LanguageServerProtocolExtensions/ResponseError+Init.swift index 3860f33df..d0db8d437 100644 --- a/Sources/LanguageServerProtocolExtensions/ResponseError+Init.swift +++ b/Sources/LanguageServerProtocolExtensions/ResponseError+Init.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitD extension ResponseError { diff --git a/Sources/LanguageServerProtocolExtensions/WorkDoneProgressManager.swift b/Sources/LanguageServerProtocolExtensions/WorkDoneProgressManager.swift index 07d35e864..58aacc500 100644 --- a/Sources/LanguageServerProtocolExtensions/WorkDoneProgressManager.swift +++ b/Sources/LanguageServerProtocolExtensions/WorkDoneProgressManager.swift @@ -11,9 +11,10 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +import ToolsProtocolsSwiftExtensions /// Represents a single `WorkDoneProgress` task that gets communicated with the client. /// diff --git a/Sources/LanguageServerProtocolJSONRPC/CMakeLists.txt b/Sources/LanguageServerProtocolJSONRPC/CMakeLists.txt deleted file mode 100644 index 1983f44aa..000000000 --- a/Sources/LanguageServerProtocolJSONRPC/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_library(LanguageServerProtocolJSONRPC STATIC - DisableSigpipe.swift - JSONRPCConnection.swift - LoggableMessageTypes.swift - MessageCoding.swift - MessageSplitting.swift) -set_target_properties(LanguageServerProtocolJSONRPC PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -target_link_libraries(LanguageServerProtocolJSONRPC PRIVATE - LanguageServerProtocol - SKLogging) -target_link_libraries(LanguageServerProtocolJSONRPC PRIVATE - $<$>:swiftDispatch> - $<$>:Foundation>) diff --git a/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift b/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift deleted file mode 100644 index c2c1c6965..000000000 --- a/Sources/LanguageServerProtocolJSONRPC/JSONRPCConnection.swift +++ /dev/null @@ -1,751 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Dispatch -public import Foundation -public import LanguageServerProtocol -import SKLogging -import SwiftExtensions - -#if canImport(Android) -import Android -#endif - -#if canImport(CDispatch) -import struct CDispatch.dispatch_fd_t -#endif - -/// A connection between a message handler (e.g. language server) in the same process as the connection object and a -/// remote message handler (e.g. language client) that may run in another process using JSON RPC messages sent over a -// pair of in/out file descriptors. -/// -/// For example, inside a language server, the `JSONRPCConnection` takes the language service implementation as its -// `receiveHandler` and itself provides the client connection for sending notifications and callbacks. -public final class JSONRPCConnection: Connection { - public enum TerminationReason: Sendable, Equatable { - /// The process on the other end of the `JSONRPCConnection` terminated with the given exit code. - case exited(exitCode: Int32) - - /// The process on the other end of the `JSONRPCConnection` terminated with a signal. The signal that it terminated - /// with is not known. - case uncaughtSignal - } - - /// A name of the endpoint for this connection, used for logging, e.g. `clangd`. - private let name: String - - /// The message handler that handles requests and notifications sent through this connection. - /// - /// Access to this must be be guaranteed to be sequential to avoid data races. Currently, all access are - /// - `init`: Reference to `JSONRPCConnection` trivially can't have escaped to other isolation domains yet. - /// - `start`: Is required to be call in the same serial code region as the initializer, so - /// `JSONRPCConnection` can't have escaped to other isolation domains yet. - /// - `deinit`: Can also only trivially be called once. - nonisolated(unsafe) private var receiveHandler: MessageHandler? - - /// The queue on which we read the data - private let queue: DispatchQueue = DispatchQueue(label: "jsonrpc-queue", qos: .userInitiated) - - /// The queue on which we send data. - private let sendQueue: DispatchQueue = DispatchQueue(label: "jsonrpc-send-queue", qos: .userInitiated) - - private let receiveIO: DispatchIO - private let sendIO: DispatchIO - private let messageRegistry: MessageRegistry - - /// If non-nil, all input received by this `JSONRPCConnection` will be written to the file handle - let inputMirrorFile: FileHandle? - - /// If non-nil, all output created by this `JSONRPCConnection` will be written to the file handle - let outputMirrorFile: FileHandle? - - enum State { - case created, running, closed - } - - /// Current state of the connection, used to ensure correct usage. - /// - /// Access to this must be be guaranteed to be sequential to avoid data races. Currently, all access are - /// - `init`: Reference to `JSONRPCConnection` trivially can't have escaped to other isolation domains yet. - /// - `start`: Is required to be called in the same serial region as the initializer, so - /// `JSONRPCConnection` can't have escaped to other isolation domains yet. - /// - `closeAssumingOnQueue`: Synchronized on `queue`. - /// - `readyToSend`: Synchronized on `queue`. - /// - `deinit`: Can also only trivially be called once. - private nonisolated(unsafe) var state: State - - /// Buffer of received bytes that haven't been parsed. - /// - /// Access to this must be be guaranteed to be sequential to avoid data races. Currently, all access are - /// - The `receiveIO` handler: This is synchronized on `queue`. - /// - `requestBufferIsEmpty`: Also synchronized on `queue`. - private nonisolated(unsafe) var requestBuffer: [UInt8] = [] - - @_spi(Testing) - public var requestBufferIsEmpty: Bool { - queue.sync { - requestBuffer.isEmpty - } - } - - /// An integer that hasn't been used for a request ID yet. - let nextRequestIDStorage = AtomicUInt32(initialValue: 0) - - struct OutstandingRequest: Sendable { - var responseType: ResponseType.Type - var replyHandler: @Sendable (LSPResult) -> Void - } - - /// The set of currently outstanding outgoing requests along with information about how to decode and handle their - /// responses. - /// - /// All accesses to `outstandingRequests` must be on `queue` to avoid race conditions. - private nonisolated(unsafe) var outstandingRequests: [RequestID: OutstandingRequest] = [:] - - /// A handler that will be called asynchronously when the connection is being - /// closed. - /// - /// There are no race conditions to `closeHandler` because it is only set from `start`, which is required to be called - /// in the same serial code region domain as the initializer, so it's serial and the `JSONRPCConnection` can't - /// have escaped to other isolation domains yet. - private nonisolated(unsafe) var closeHandler: (@Sendable () async -> Void)? = nil - - /// - Important: `start` must be called before sending any data over the `JSONRPCConnection`. - public init( - name: String, - protocol messageRegistry: MessageRegistry, - inFD: FileHandle, - outFD: FileHandle, - inputMirrorFile: FileHandle? = nil, - outputMirrorFile: FileHandle? = nil - ) { - self.name = name - self.inputMirrorFile = inputMirrorFile - self.outputMirrorFile = outputMirrorFile - self.receiveHandler = nil - globallyDisableSigpipeIfNeeded() - state = .created - self.messageRegistry = messageRegistry - - let ioGroup = DispatchGroup() - - #if os(Windows) - let rawInFD = dispatch_fd_t(bitPattern: inFD._handle) - #else - let rawInFD = inFD.fileDescriptor - #endif - - ioGroup.enter() - receiveIO = DispatchIO( - type: .stream, - fileDescriptor: rawInFD, - queue: queue, - cleanupHandler: { (error: Int32) in - if error != 0 { - logger.fault("IO error \(error)") - } - ioGroup.leave() - } - ) - - #if os(Windows) - let rawOutFD = dispatch_fd_t(bitPattern: outFD._handle) - #else - let rawOutFD = outFD.fileDescriptor - #endif - - ioGroup.enter() - sendIO = DispatchIO( - type: .stream, - fileDescriptor: rawOutFD, - queue: sendQueue, - cleanupHandler: { (error: Int32) in - if error != 0 { - logger.fault("IO error \(error)") - } - ioGroup.leave() - } - ) - - ioGroup.notify(queue: queue) { [weak self] in - guard let self else { return } - for outstandingRequest in self.outstandingRequests.values { - outstandingRequest.replyHandler(LSPResult.failure(ResponseError.internalError("JSON-RPC Connection closed"))) - } - self.outstandingRequests = [:] - self.receiveHandler = nil // break retain cycle - Task { - await self.closeHandler?() - } - } - - // We cannot assume the client will send us bytes in packets of any particular size, so set the lower limit to 1. - receiveIO.setLimit(lowWater: 1) - receiveIO.setLimit(highWater: Int.max) - - sendIO.setLimit(lowWater: 1) - sendIO.setLimit(highWater: Int.max) - } - - /// Creates and starts a `JSONRPCConnection` that connects to a subprocess launched with the specified arguments. - /// - /// `client` is the message handler that handles the messages sent from the subprocess to SourceKit-LSP. - public static func start( - executable: URL, - arguments: [String], - name: StaticString, - protocol messageRegistry: MessageRegistry, - stderrLoggingCategory: String, - client: MessageHandler, - terminationHandler: @Sendable @escaping (_ terminationReason: TerminationReason) -> Void - ) throws -> (connection: JSONRPCConnection, process: Process) { - let clientToServer = Pipe() - let serverToClient = Pipe() - - let connection = JSONRPCConnection( - name: "\(name)", - protocol: messageRegistry, - inFD: serverToClient.fileHandleForReading, - outFD: clientToServer.fileHandleForWriting - ) - - connection.start(receiveHandler: client) { - // Keep the pipes alive until we close the connection. - withExtendedLifetime((clientToServer, serverToClient)) {} - } - let process = Foundation.Process() - logger.log( - "Launching JSON-RPC connection to \(executable.description) with options [\(arguments.joined(separator: " "))]" - ) - process.executableURL = executable - process.arguments = arguments - process.standardOutput = serverToClient - process.standardInput = clientToServer - let logForwarder = PipeAsStringHandler { - Logger(subsystem: LoggingScope.subsystem, category: stderrLoggingCategory).info("\($0)") - } - let stderrHandler = Pipe() - stderrHandler.fileHandleForReading.readabilityHandler = { fileHandle in - let newData = fileHandle.availableData - if newData.count == 0 { - stderrHandler.fileHandleForReading.readabilityHandler = nil - } else { - logForwarder.handleDataFromPipe(newData) - } - } - process.standardError = stderrHandler - process.terminationHandler = { process in - logger.log( - level: process.terminationReason == .exit ? .default : .error, - "\(name) exited: \(process.terminationReason.rawValue) \(process.terminationStatus)" - ) - connection.close() - let terminationReason: TerminationReason - switch process.terminationReason { - case .exit: - terminationReason = .exited(exitCode: process.terminationStatus) - case .uncaughtSignal: - terminationReason = .uncaughtSignal - @unknown default: - logger.fault( - "Process terminated with unknown termination reason: \(process.terminationReason.rawValue, privacy: .public)" - ) - terminationReason = .exited(exitCode: 0) - } - terminationHandler(terminationReason) - } - try process.run() - - return (connection, process) - } - - deinit { - assert(state == .closed) - } - - /// Change the handler that handles messages from the JSON-RPC connection to a new handler. - public func changeReceiveHandler(_ receiveHandler: MessageHandler) { - queue.sync { - self.receiveHandler = receiveHandler - } - } - - /// Start processing `inFD` and send messages to `receiveHandler`. - /// - /// - parameter receiveHandler: The message handler to invoke for requests received on the `inFD`. - /// - /// - Important: `start` must be called before sending any data over the `JSONRPCConnection`. - public func start( - receiveHandler: MessageHandler, - closeHandler: @escaping @Sendable () async -> Void = {} - ) { - queue.sync { - precondition(state == .created) - state = .running - self.receiveHandler = receiveHandler - self.closeHandler = closeHandler - - receiveIO.read(offset: 0, length: Int.max, queue: queue) { done, data, errorCode in - guard errorCode == 0 else { - #if !os(Windows) - if errorCode != POSIXError.ECANCELED.rawValue { - logger.fault("IO error reading \(errorCode)") - } - #endif - if done { self.closeAssumingOnQueue() } - return - } - - if done { - self.closeAssumingOnQueue() - return - } - - guard let data = data, !data.isEmpty else { - return - } - - orLog("Writing input mirror file") { - try self.inputMirrorFile?.write(contentsOf: data) - } - - // Parse and handle any messages in `buffer + data`, leaving any remaining unparsed bytes in `buffer`. - if self.requestBuffer.isEmpty { - data.withUnsafeBytes { (pointer: UnsafePointer) in - let rest = self.parseAndHandleMessages(from: UnsafeBufferPointer(start: pointer, count: data.count)) - self.requestBuffer.append(contentsOf: rest) - } - } else { - self.requestBuffer.append(contentsOf: data) - var unused = 0 - self.requestBuffer.withUnsafeBufferPointer { buffer in - let rest = self.parseAndHandleMessages(from: buffer) - unused = rest.count - } - self.requestBuffer.removeFirst(self.requestBuffer.count - unused) - } - } - } - } - - /// Send a notification to the client that informs the user about a message encoding or decoding error and asks them - /// to file an issue. - /// - /// `message` describes what has gone wrong to the user. - /// - /// - Important: Must be called on `queue` - private func sendMessageCodingErrorNotificationToClient(message: String) { - dispatchPrecondition(condition: .onQueue(queue)) - let showMessage = ShowMessageNotification( - type: .error, - message: """ - \(message). Please run 'sourcekit-lsp diagnose' to file an issue. - """ - ) - self.send(.notification(showMessage)) - } - - /// Decode a single JSONRPC message from the given `messageBytes`. - /// - /// `messageBytes` should be valid JSON, ie. this is the message sent from the client without the `Content-Length` - /// header. - /// - /// If an error occurs during message parsing, this tries to recover as gracefully as possible and returns `nil`. - /// Callers should consider the message handled and ignore it when this function returns `nil`. - /// - /// - Important: Must be called on `queue` - private func decodeJSONRPCMessage(messageBytes: Slice>) -> JSONRPCMessage? { - dispatchPrecondition(condition: .onQueue(queue)) - let decoder = JSONDecoder() - - // Set message registry to use for model decoding. - decoder.userInfo[.messageRegistryKey] = messageRegistry - - // Setup callback for response type. - decoder.userInfo[.responseTypeCallbackKey] = { @Sendable (id: RequestID) -> ResponseType.Type? in - // `outstandingRequests` should never be mutated in this closure. Reading is fine as all of our other writes are - // guarded by `queue`, but `JSONDecoder` could (since this is sendable) invoke this concurrently. - guard let outstanding = self.outstandingRequests[id] else { - logger.error("Unknown request for \(id, privacy: .public)") - return nil - } - return outstanding.responseType - } - - do { - let pointer = UnsafeMutableRawPointer(mutating: UnsafeBufferPointer(rebasing: messageBytes).baseAddress!) - return try decoder.decode( - JSONRPCMessage.self, - from: Data(bytesNoCopy: pointer, count: messageBytes.count, deallocator: .none) - ) - } catch let error as MessageDecodingError { - logger.fault("Failed to decode message: \(error.forLogging)") - logger.fault("Malformed message: \(String(bytes: messageBytes, encoding: .utf8) ?? "")") - - // We failed to decode the message. Under those circumstances try to behave as LSP-conforming as possible. - // Always log at the fault level so that we know something is going wrong from the logs. - // - // The pattern below is to handle the message in the best possible way and then `return nil` to acknowledge the - // handling. That way the compiler enforces that we handle all code paths. - switch error.messageKind { - case .request: - if let id = error.id { - // If we know it was a request and we have the request ID, simply reply to the request and tell the client - // that we couldn't parse it. That complies with LSP that all requests should eventually get a response. - logger.fault( - "Replying to request \(id, privacy: .public) with error response because we failed to decode the request" - ) - self.send(.errorResponse(ResponseError(error), id: id)) - return nil - } - // If we don't know the ID of the request, ignore it and show a notification to the user. - // That way the user at least knows that something is going wrong even if the client never gets a response - // for the request. - logger.fault("Ignoring request because we failed to decode the request and don't have a request ID") - sendMessageCodingErrorNotificationToClient(message: "sourcekit-lsp failed to decode a request") - return nil - case .response: - if let id = error.id { - if let outstanding = self.outstandingRequests.removeValue(forKey: id) { - // If we received a response to a request we sent to the client, assume that the client responded with an - // error. That complies with LSP that all requests should eventually get a response. - logger.fault( - "Assuming an error response to request \(id, privacy: .public) because response from client could not be decoded" - ) - outstanding.replyHandler(.failure(ResponseError(error))) - return nil - } - // If there's an error in the response but we don't even know about the request, we can ignore it. - logger.fault( - "Ignoring response to request \(id, privacy: .public) because it could not be decoded and given request ID is unknown" - ) - return nil - } - // And if we can't even recover the ID the response is for, we drop it. This means that whichever code in - // sourcekit-lsp sent the request will probably never get a reply but there's nothing we can do about that. - // Ideally requests sent from sourcekit-lsp to the client would have some kind of timeout anyway. - logger.fault("Ignoring response because its request ID could not be recovered") - return nil - case .notification: - if error.code == .methodNotFound { - // If we receive a notification we don't know about, this might be a client sending a new LSP notification - // that we don't know about. It can't be very critical so we ignore it without bothering the user with an - // error notification. - logger.fault("Ignoring notification because we don't know about it's method") - return nil - } - // Ignoring any other notification might result in corrupted behavior. For example, ignoring a - // `textDocument/didChange` will result in an out-of-sync state between the editor and sourcekit-lsp. - // Warn the user about the error. - logger.fault("Ignoring notification that may cause corrupted behavior") - sendMessageCodingErrorNotificationToClient(message: "sourcekit-lsp failed to decode a notification") - return nil - case .unknown: - // We don't know what has gone wrong. This could be any level of badness. Inform the user about it. - logger.fault("Ignoring unknown message") - sendMessageCodingErrorNotificationToClient(message: "sourcekit-lsp failed to decode a message") - return nil - } - } catch { - // We don't know what has gone wrong. This could be any level of badness. Inform the user about it and ignore the - // message. - logger.fault("Ignoring unknown message") - sendMessageCodingErrorNotificationToClient(message: "sourcekit-lsp failed to decode an unknown message") - return nil - } - } - - /// Whether we can send messages in the current state. - /// - /// - parameter shouldLog: Whether to log an info message if not ready. - /// - /// - Important: Must be called on `queue`. Note that the state might change as soon as execution leaves `queue`. - func readyToSend(shouldLog: Bool = true) -> Bool { - dispatchPrecondition(condition: .onQueue(queue)) - precondition(state != .created, "tried to send message before calling start(messageHandler:)") - let ready = state == .running - if shouldLog && !ready { - logger.error("Ignoring message; state = \(String(reflecting: self.state), privacy: .public)") - } - return ready - } - - /// Parse and handle all messages in `bytes`, returning a slice containing any remaining incomplete data. - /// - /// - Important: Must be called on `queue` - func parseAndHandleMessages(from bytes: UnsafeBufferPointer) -> UnsafeBufferPointer.SubSequence { - dispatchPrecondition(condition: .onQueue(queue)) - - var bytes = bytes[...] - - MESSAGE_LOOP: while true { - // Split the messages based on the Content-Length header. - let messageBytes: Slice> - do { - guard let (header: _, message: message, rest: rest) = try bytes.jsonrpcSplitMessage() else { - return bytes - } - messageBytes = message - bytes = rest - } catch { - // We failed to parse the message header. There isn't really much we can do to recover because we lost our - // anchor in the stream where new messages start. Crashing and letting ourselves be restarted by the client is - // probably the best option. - sendMessageCodingErrorNotificationToClient(message: "Failed to find next message in connection to editor") - fatalError("fatal error encountered while splitting JSON RPC messages \(error)") - } - - guard let message = decodeJSONRPCMessage(messageBytes: messageBytes) else { - continue - } - handle(message) - } - } - - /// Handle a single message by dispatching it to `receiveHandler` or an appropriate reply handler. - /// - /// - Important: Must be called on `queue` - func handle(_ message: JSONRPCMessage) { - dispatchPrecondition(condition: .onQueue(queue)) - switch message { - case .notification(let notification): - notification._handle(self.receiveHandler!) - case .request(let request, let id): - request._handle(self.receiveHandler!, id: id) { (response, id) in - self.sendReply(response, id: id) - } - case .response(let response, let id): - guard let outstanding = outstandingRequests.removeValue(forKey: id) else { - logger.error("No outstanding requests for response ID \(id, privacy: .public)") - return - } - outstanding.replyHandler(.success(response)) - case .errorResponse(let error, let id): - guard let id = id else { - logger.error("Received error response for unknown request: \(error.forLogging)") - return - } - guard let outstanding = outstandingRequests.removeValue(forKey: id) else { - logger.error("No outstanding requests for error response ID \(id, privacy: .public)") - return - } - outstanding.replyHandler(.failure(error)) - } - } - - /// Send the raw data to the receiving end of this connection. - /// - /// If an unrecoverable error occurred on the channel's file descriptor, the connection gets closed. - /// - /// - Important: Must be called on `queue` - private func send(data dispatchData: DispatchData) { - dispatchPrecondition(condition: .onQueue(queue)) - guard readyToSend() else { return } - - orLog("Writing output mirror file") { - try outputMirrorFile?.write(contentsOf: dispatchData) - } - sendIO.write(offset: 0, data: dispatchData, queue: sendQueue) { [weak self] done, _, errorCode in - if errorCode != 0 { - logger.fault("IO error sending message \(errorCode)") - if done, let self { - // An unrecoverable error occurs on the channel’s file descriptor. - // Close the connection. - self.queue.async { - self.closeAssumingOnQueue() - } - } - } - } - } - - /// Wrapper of `send(data:)` that automatically switches to `queue`. - /// - /// This should only be used to test that the client decodes messages correctly if data is delivered to it - /// byte-by-byte instead of in larger chunks that contain entire messages. - @_spi(Testing) - public func send(_rawData dispatchData: DispatchData) { - queue.sync { - self.send(data: dispatchData) - } - } - - /// Send the given message to the receiving end of the connection. - /// - /// If an unrecoverable error occurred on the channel's file descriptor, the connection gets closed. - /// - /// - Important: Must be called on `queue` - func send(_ message: JSONRPCMessage) { - dispatchPrecondition(condition: .onQueue(queue)) - - let encoder = JSONEncoder() - - let data: Data - do { - data = try encoder.encode(message) - } catch { - logger.fault("Failed to encode message: \(error.forLogging)") - logger.fault("Malformed message: \(String(describing: message))") - switch message { - case .notification(_): - // We want to send a notification to the editor but failed to encode it. Since dropping the notification might - // result in getting out-of-sync state-wise with the editor (eg. for work progress notifications), inform the - // user about it. - sendMessageCodingErrorNotificationToClient( - message: "sourcekit-lsp failed to encode a notification to the editor" - ) - return - case .request(_, _): - // We want to send a notification to the editor but failed to encode it. We don't know the `reply` handle for - // the request at this point so we can't synthesize an errorResponse for the request. This means that the - // request will never receive a reply. Inform the user about it. - sendMessageCodingErrorNotificationToClient( - message: "sourcekit-lsp failed to encode a request to the editor" - ) - return - case .response(_, _): - // The editor sent a request to sourcekit-lsp, which failed but we can't serialize the result back to the - // client. This means that the request will never receive a reply. Inform the user about it and accept that - // we'll never send a reply. - sendMessageCodingErrorNotificationToClient( - message: "sourcekit-lsp failed to encode a response to the editor" - ) - return - case .errorResponse(_, _): - // Same as `.response`. Has an optional `id`, so can't share the case. - sendMessageCodingErrorNotificationToClient( - message: "sourcekit-lsp failed to encode an error response to the editor" - ) - return - } - } - - var dispatchData = DispatchData.empty - let header = "Content-Length: \(data.count)\r\n\r\n" - header.utf8.map { $0 }.withUnsafeBytes { buffer in - dispatchData.append(buffer) - } - data.withUnsafeBytes { rawBufferPointer in - dispatchData.append(rawBufferPointer) - } - - send(data: dispatchData) - } - - /// Close the connection. - /// - /// The user-provided close handler will be called *asynchronously* when all outstanding I/O - /// operations have completed. No new I/O will be accepted after `close` returns. - public func close() { - queue.sync { closeAssumingOnQueue() } - } - - /// Close the connection, assuming that the code is already executing on `queue`. - /// - /// - Important: Must be called on `queue`. - private func closeAssumingOnQueue() { - dispatchPrecondition(condition: .onQueue(queue)) - sendQueue.sync { - guard state == .running else { return } - state = .closed - - logger.log("Closing JSONRPCConnection...") - // Attempt to close the reader immediately; we do not need to accept remaining inputs. - receiveIO.close(flags: .stop) - // Close the writer after it finishes outstanding work. - sendIO.close() - } - } - - /// Request id for the next outgoing request. - public func nextRequestID() -> RequestID { - return .string("sk-\(nextRequestIDStorage.fetchAndIncrement())") - } - - // MARK: Connection interface - - /// Send the notification to the remote side of the notification. - public func send(_ notification: some NotificationType) { - queue.async { - logger.info( - """ - Sending notification to \(self.name, privacy: .public) - \(notification.forLogging) - """ - ) - self.send(.notification(notification)) - } - } - - /// Send the given request to the remote side of the connection. - /// - /// When the receiving end replies to the request, execute `reply` with the response. - public func send( - _ request: Request, - id: RequestID, - reply: @escaping @Sendable (LSPResult) -> Void - ) { - self.queue.sync { - guard readyToSend() else { - reply(.failure(.serverCancelled)) - return - } - - outstandingRequests[id] = OutstandingRequest( - responseType: Request.Response.self, - replyHandler: { anyResult in - let result = anyResult.map { $0 as! Request.Response } - switch result { - case .success(let response): - logger.info( - """ - Received reply for request \(id, privacy: .public) from \(self.name, privacy: .public) - \(Request.method, privacy: .public) - \(response.forLogging) - """ - ) - case .failure(let error): - logger.error( - """ - Received error for request \(id, privacy: .public) from \(self.name, privacy: .public) - \(Request.method, privacy: .public) - \(error.forLogging) - """ - ) - } - reply(result) - } - ) - logger.info( - """ - Sending request to \(self.name, privacy: .public) (id: \(id, privacy: .public)): - \(request.forLogging) - """ - ) - - send(.request(request, id: id)) - return - } - } - - /// After the remote side of the connection sent a request to us, return a reply to the remote side. - public func sendReply(_ response: LSPResult, id: RequestID) { - queue.async { - switch response { - case .success(let result): - self.send(.response(result, id: id)) - case .failure(let error): - self.send(.errorResponse(error, id: id)) - } - } - } -} diff --git a/Sources/LanguageServerProtocolJSONRPC/LoggableMessageTypes.swift b/Sources/LanguageServerProtocolJSONRPC/LoggableMessageTypes.swift deleted file mode 100644 index 5da77bf20..000000000 --- a/Sources/LanguageServerProtocolJSONRPC/LoggableMessageTypes.swift +++ /dev/null @@ -1,105 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -package import LanguageServerProtocol -package import SKLogging - -// MARK: - RequestType - -package struct AnyRequestType: CustomLogStringConvertible { - let request: any RequestType - - package init(request: any RequestType) { - self.request = request - } - - package var description: String { - return """ - \(type(of: request).method) - \(request.prettyPrintedJSON) - """ - } - - package var redactedDescription: String { - return """ - \(type(of: request).method) - \(request.prettyPrintedRedactedJSON) - """ - } -} - -extension RequestType { - package var forLogging: CustomLogStringConvertibleWrapper { - return AnyRequestType(request: self).forLogging - } -} - -// MARK: - NotificationType - -package struct AnyNotificationType: CustomLogStringConvertible { - let notification: any NotificationType - - package init(notification: any NotificationType) { - self.notification = notification - } - - package var description: String { - return """ - \(type(of: notification).method) - \(notification.prettyPrintedJSON) - """ - } - - package var redactedDescription: String { - return """ - \(type(of: notification).method) - \(notification.prettyPrintedRedactedJSON) - """ - } -} - -extension NotificationType { - package var forLogging: CustomLogStringConvertibleWrapper { - return AnyNotificationType(notification: self).forLogging - } -} - -// MARK: - ResponseType - -package struct AnyResponseType: CustomLogStringConvertible { - let response: any ResponseType - - package init(response: any ResponseType) { - self.response = response - } - - package var description: String { - return """ - \(type(of: response)) - \(response.prettyPrintedJSON) - """ - } - - package var redactedDescription: String { - return """ - \(type(of: response)) - \(response.prettyPrintedRedactedJSON) - """ - } -} - -extension ResponseType { - package var forLogging: CustomLogStringConvertibleWrapper { - return AnyResponseType(response: self).forLogging - } -} diff --git a/Sources/LanguageServerProtocolJSONRPC/MessageCoding.swift b/Sources/LanguageServerProtocolJSONRPC/MessageCoding.swift deleted file mode 100644 index 1bfac6bde..000000000 --- a/Sources/LanguageServerProtocolJSONRPC/MessageCoding.swift +++ /dev/null @@ -1,165 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -public import LanguageServerProtocol - -@_spi(Testing) public enum JSONRPCMessage { - case notification(NotificationType) - case request(_RequestType, id: RequestID) - case response(ResponseType, id: RequestID) - case errorResponse(ResponseError, id: RequestID?) -} - -extension CodingUserInfoKey { - public static let responseTypeCallbackKey: CodingUserInfoKey = CodingUserInfoKey( - rawValue: "lsp.jsonrpc.responseTypeCallback" - )! - public static let messageRegistryKey: CodingUserInfoKey = CodingUserInfoKey(rawValue: "lsp.jsonrpc.messageRegistry")! -} - -extension JSONRPCMessage: Codable { - - public typealias ResponseTypeCallback = @Sendable (RequestID) -> ResponseType.Type? - - private enum CodingKeys: String, CodingKey { - case jsonrpc - case method - case id - case params - case result - case error - } - - public init(from decoder: Decoder) throws { - - guard let messageRegistry = decoder.userInfo[.messageRegistryKey] as? MessageRegistry else { - fatalError("missing or invalid messageRegistryKey on decoder") - } - let container = try decoder.container(keyedBy: CodingKeys.self) - let jsonrpc = try container.decodeIfPresent(String.self, forKey: .jsonrpc) - let id = try container.decodeIfPresent(RequestID.self, forKey: .id) - var msgKind = MessageDecodingError.MessageKind.unknown - - if jsonrpc != "2.0" { - throw MessageDecodingError.invalidRequest("jsonrpc version must be 2.0") - } - - do { - let method = try container.decodeIfPresent(String.self, forKey: .method) - let error = try container.decodeIfPresent(ResponseError.self, forKey: .error) - - let hasResult = container.contains(.result) - - switch (id, method, hasResult, error) { - case (nil, let method?, _, nil): - msgKind = .notification - - guard let messageType = messageRegistry.notificationType(for: method) else { - throw MessageDecodingError.methodNotFound(method) - } - - let params = try messageType.init(from: container.superDecoder(forKey: .params)) - - self = .notification(params) - - case (let id?, let method?, _, nil): - msgKind = .request - - guard let messageType = messageRegistry.requestType(for: method) else { - throw MessageDecodingError.methodNotFound(method) - } - - let params = try messageType.init(from: container.superDecoder(forKey: .params)) - - self = .request(params, id: id) - - case (let id?, nil, true, nil): - msgKind = .response - - guard let responseTypeCallback = decoder.userInfo[.responseTypeCallbackKey] as? ResponseTypeCallback else { - fatalError("missing or invalid responseTypeCallbackKey on decoder") - } - - guard let responseType = responseTypeCallback(id) else { - throw MessageDecodingError.invalidParams("response to unknown request \(id)") - } - - let result = try responseType.init(from: container.superDecoder(forKey: .result)) - - self = .response(result, id: id) - - case (let id, nil, _, let error?): - msgKind = .response - self = .errorResponse(error, id: id) - - default: - throw MessageDecodingError.invalidRequest("message not recognized as request, response or notification") - } - - } catch var error as MessageDecodingError { - assert(error.id == nil || error.id == id) - error.id = id - error.messageKind = msgKind - throw error - - } catch DecodingError.keyNotFound(let key, _) { - throw MessageDecodingError.invalidParams( - "missing expected parameter: \(key.stringValue)", - id: id, - messageKind: msgKind - ) - - } catch DecodingError.valueNotFound(_, let context) { - throw MessageDecodingError.invalidParams( - "missing expected parameter: \(context.codingPath.last?.stringValue ?? "unknown")", - id: id, - messageKind: msgKind - ) - - } catch DecodingError.typeMismatch(_, let context) { - let path = context.codingPath.map { $0.stringValue }.joined(separator: ".") - throw MessageDecodingError.invalidParams( - "type mismatch at \(path) : \(context.debugDescription)", - id: id, - messageKind: msgKind - ) - - } catch { - throw MessageDecodingError.parseError(error.localizedDescription, id: id, messageKind: msgKind) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode("2.0", forKey: .jsonrpc) - - switch self { - case .notification(let params): - try container.encode(type(of: params).method, forKey: .method) - try params.encode(to: container.superEncoder(forKey: .params)) - - case .request(let params, let id): - try container.encode(type(of: params).method, forKey: .method) - try container.encode(id, forKey: .id) - try params.encode(to: container.superEncoder(forKey: .params)) - - case .response(let result, let id): - try container.encode(id, forKey: .id) - try result.encode(to: container.superEncoder(forKey: .result)) - - case .errorResponse(let error, let id): - try container.encode(id, forKey: .id) - try container.encode(error, forKey: .error) - } - } -} diff --git a/Sources/LanguageServerProtocolJSONRPC/MessageSplitting.swift b/Sources/LanguageServerProtocolJSONRPC/MessageSplitting.swift deleted file mode 100644 index 696a6315a..000000000 --- a/Sources/LanguageServerProtocolJSONRPC/MessageSplitting.swift +++ /dev/null @@ -1,179 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -import LanguageServerProtocol - -public struct JSONRPCMessageHeader: Hashable { - static let contentLengthKey: [UInt8] = [UInt8]("Content-Length".utf8) - static let separator: [UInt8] = [UInt8]("\r\n".utf8) - static let colon: UInt8 = UInt8(ascii: ":") - static let invalidKeyBytes: [UInt8] = [colon] + separator - - public var contentLength: Int? = nil - - public init(contentLength: Int? = nil) { - self.contentLength = contentLength - } -} - -extension RandomAccessCollection where Index == Int { - /// Tries to parse a single message from this collection of bytes. - /// - /// If an entire message could be found, returns - /// - header (representing `Content-Length:\r\n\r\n`) - /// - message: The data that represents the actual message as JSON - /// - rest: The remaining bytes that haven't weren't part of the first message in this collection - /// - /// If a `Content-Length` header could be found but the collection doesn't have enough bytes for the entire message - /// (eg. because the `Content-Length` header has been transmitted yet but not the entire message), returns `nil`. - /// Callers should call this method again once more data is available. - @_spi(Testing) - public func jsonrpcSplitMessage() throws -> (header: JSONRPCMessageHeader, message: SubSequence, rest: SubSequence)? { - guard let (header, rest) = try jsonrcpParseHeader() else { return nil } - guard let contentLength = header.contentLength else { - throw MessageDecodingError.parseError("missing Content-Length header") - } - if contentLength > rest.count { return nil } - return (header: header, message: rest.prefix(contentLength), rest: rest.dropFirst(contentLength)) - } - - @_spi(Testing) - public func jsonrcpParseHeader() throws -> (header: JSONRPCMessageHeader, rest: SubSequence)? { - var header = JSONRPCMessageHeader() - var slice = self[...] - while let (kv, rest) = try slice.jsonrpcParseHeaderField() { - guard let (key, value) = kv else { - return (header, rest) - } - slice = rest - - if key.elementsEqual(JSONRPCMessageHeader.contentLengthKey) { - guard let count = Int(ascii: value) else { - throw MessageDecodingError.parseError( - "expected integer value in \(String(bytes: value, encoding: .utf8) ?? "")" - ) - } - header.contentLength = count - } - - // Unknown field, continue. - } - return nil - } - - @_spi(Testing) - public func jsonrpcParseHeaderField() throws -> ((key: SubSequence, value: SubSequence)?, SubSequence)? { - if starts(with: JSONRPCMessageHeader.separator) { - return (nil, dropFirst(JSONRPCMessageHeader.separator.count)) - } else if first == JSONRPCMessageHeader.separator.first { - return nil - } - - guard let keyEnd = firstIndex(where: { JSONRPCMessageHeader.invalidKeyBytes.contains($0) }) else { - return nil - } - if self[keyEnd] != JSONRPCMessageHeader.colon { - throw MessageDecodingError.parseError("expected ':' in message header") - } - let valueStart = index(after: keyEnd) - guard let valueEnd = self[valueStart...].firstRange(of: JSONRPCMessageHeader.separator)?.startIndex else { - return nil - } - - return ((key: self[..(ascii buffer: C) where C: Collection, C.Element == UInt8 { - guard !buffer.isEmpty else { return nil } - - // Trim leading whitespace. - var i = buffer.startIndex - while i != buffer.endIndex, buffer[i].isSpace { - i = buffer.index(after: i) - } - - guard i != buffer.endIndex else { return nil } - - // Check sign if any. - var sign = 1 - if buffer[i] == UInt8(ascii: "+") { - i = buffer.index(after: i) - } else if buffer[i] == UInt8(ascii: "-") { - i = buffer.index(after: i) - sign = -1 - } - - guard i != buffer.endIndex, buffer[i].isDigit else { return nil } - - // Accumulate the result. - var result = 0 - while i != buffer.endIndex, buffer[i].isDigit { - result = result * 10 + sign * buffer[i].asciiDigit - i = buffer.index(after: i) - } - - // Trim trailing whitespace. - while i != buffer.endIndex { - if !buffer[i].isSpace { return nil } - i = buffer.index(after: i) - } - self = result - } - - // Constructs an integer from a buffer of base-10 ascii digits, ignoring any surrounding whitespace. - /// - /// This is similar to `atol` but with several advantages: - /// - no need to construct a null-terminated C string - /// - overflow will trap instead of being undefined - /// - does not allow non-whitespace characters at the end - @inlinable - public init?(ascii buffer: S) where S: StringProtocol { - self.init(ascii: buffer.utf8) - } -} diff --git a/Sources/SKLogging/CMakeLists.txt b/Sources/SKLogging/CMakeLists.txt deleted file mode 100644 index 1c9b6a9f6..000000000 --- a/Sources/SKLogging/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -set(sources - CustomLogStringConvertible.swift - Error+ForLogging.swift - Logging.swift - LoggingScope.swift - NonDarwinLogging.swift - OrLog.swift - SetGlobalLogFileHandler.swift - SplitLogMessage.swift) - -add_library(SKLogging STATIC ${sources}) -set_target_properties(SKLogging PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -target_link_libraries(SKLogging PRIVATE - $<$>:Foundation>) -target_link_libraries(SKLogging PUBLIC - SwiftExtensions - Crypto) - -add_library(SKLoggingForPlugin STATIC ${sources}) -set_target_properties(SKLoggingForPlugin PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -target_compile_options(SKLoggingForPlugin PRIVATE - $<$: - -DNO_CRYPTO_DEPENDENCY; - "SHELL:-module-alias SwiftExtensions=SwiftExtensionsForPlugin" - >) -target_link_libraries(SKLoggingForPlugin PRIVATE - $<$>:Foundation>) -target_link_libraries(SKLoggingForPlugin PUBLIC - SwiftExtensionsForPlugin) diff --git a/Sources/SKLogging/CustomLogStringConvertible.swift b/Sources/SKLogging/CustomLogStringConvertible.swift deleted file mode 100644 index 573561606..000000000 --- a/Sources/SKLogging/CustomLogStringConvertible.swift +++ /dev/null @@ -1,150 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -public import Foundation - -#if !NO_CRYPTO_DEPENDENCY -import Crypto -#endif - -/// An object that can printed for logging and also offers a redacted description -/// when logging in contexts in which private information shouldn't be captured. -package protocol CustomLogStringConvertible: CustomStringConvertible, Sendable { - /// A full description of the object. - var description: String { get } - - /// A description of the object that doesn't contain any private information. - var redactedDescription: String { get } -} - -/// When an NSObject is logged with OSLog in private mode and the object -/// implements `redactedDescription`, OSLog will log that information instead of -/// just logging ``. -/// -/// There currently is no way to get equivalent functionality in pure Swift. We -/// thus pass this object to OSLog, which just forwards to `description` or -/// `redactedDescription` of an object that implements `CustomLogStringConvertible`. -public final class CustomLogStringConvertibleWrapper: NSObject, Sendable { - // `CustomLogStringConvertibleWrapper` is marked as `public` to work around - // https://github.com/swiftlang/swift/issues/83893 - private let underlyingObject: any CustomLogStringConvertible - #if compiler(>=6.4) - #warning( - "Mark CustomLogStringConvertibleWrapper as `package` if https://github.com/swiftlang/swift/issues/83893 is fixed" - ) - #endif - - fileprivate init(_ underlyingObject: any CustomLogStringConvertible) { - self.underlyingObject = underlyingObject - } - - public override var description: String { - return underlyingObject.description - } - - #if canImport(os) - // When using OSLog mark redactedDescription as @objc so that OSLog can find it via the Objective-C runtime. - // We can't unconditionally mark it as @objc because eg. Linux doesn't have the Objective-C runtime. - @objc - #endif - package var redactedDescription: String { - underlyingObject.redactedDescription - } -} - -extension CustomLogStringConvertible { - /// Returns an object that can be passed to OSLog, which will print the - /// `redactedDescription` if logging of private information is disabled and - /// will log `description` otherwise. - package var forLogging: CustomLogStringConvertibleWrapper { - return CustomLogStringConvertibleWrapper(self) - } -} - -extension String { - /// A hash value that can be logged in a redacted description without - /// disclosing any private information about the string. - package var hashForLogging: String { - #if NO_CRYPTO_DEPENDENCY - return "" - #else - let hash = SHA256.hash(data: Data(self.utf8)).prefix(8).map { String(format: "%02x", $0) }.joined() - return "" - #endif - } -} - -private struct OptionalWrapper: CustomLogStringConvertible where Wrapped: CustomLogStringConvertible { - let optional: Wrapped? - - package var description: String { - return optional?.description ?? "" - } - - package var redactedDescription: String { - return optional?.redactedDescription ?? "" - } -} - -extension Optional where Wrapped: CustomLogStringConvertible { - package var forLogging: CustomLogStringConvertibleWrapper { - return CustomLogStringConvertibleWrapper(OptionalWrapper(optional: self)) - } -} - -extension Encodable { - package var prettyPrintedJSON: String { - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes] - guard let data = try? encoder.encode(self) else { - return "\(self)" - } - guard let string = String(data: data, encoding: .utf8) else { - return "\(self)" - } - // Don't escape '/'. Most JSON readers don't need it escaped and it makes - // paths a lot easier to read and copy-paste. - return string.replacingOccurrences(of: "\\/", with: "/") - } - - package var prettyPrintedRedactedJSON: String { - func redact(subject: Any) -> Any { - if let subject = subject as? [String: Any] { - return subject.mapValues { redact(subject: $0) } - } else if let subject = subject as? [Any] { - return subject.map { redact(subject: $0) } - } else if let subject = subject as? String { - return subject.hashForLogging - } else if let subject = subject as? Int { - return subject - } else if let subject = subject as? Double { - return subject - } else if let subject = subject as? Bool { - return subject - } else { - return "" - } - } - - guard let encoded = try? JSONEncoder().encode(self), - let jsonObject = try? JSONSerialization.jsonObject(with: encoded), - let data = try? JSONSerialization.data( - withJSONObject: redact(subject: jsonObject), - options: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes] - ), - let string = String(data: data, encoding: .utf8) - else { - return "" - } - return string - } -} diff --git a/Sources/SKLogging/Error+ForLogging.swift b/Sources/SKLogging/Error+ForLogging.swift deleted file mode 100644 index 023536e4f..000000000 --- a/Sources/SKLogging/Error+ForLogging.swift +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// A wrapper around `Error` that conforms to `CustomLogStringConvertible`. -private struct MaskedError: CustomLogStringConvertible { - let underlyingError: any Error - - init(_ underlyingError: any Error) { - self.underlyingError = underlyingError - } - - var description: String { - return "\(underlyingError)" - } - - var redactedDescription: String { - let error = underlyingError as NSError - return "\(error.code): \(error.description.hashForLogging)" - } -} - -extension Error { - /// A version of the error that can be used for logging and will only log the - /// error code and a hash of the description in privacy-sensitive contexts. - package var forLogging: CustomLogStringConvertibleWrapper { - if let error = self as? CustomLogStringConvertible { - return error.forLogging - } else { - return MaskedError(self).forLogging - } - } -} diff --git a/Sources/SKLogging/Logging.swift b/Sources/SKLogging/Logging.swift deleted file mode 100644 index 14905aa21..000000000 --- a/Sources/SKLogging/Logging.swift +++ /dev/null @@ -1,48 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -#if canImport(os) && !SOURCEKIT_LSP_FORCE_NON_DARWIN_LOGGER -@_exported public import os // os_log - -package typealias LogLevel = os.OSLogType -package typealias Logger = os.Logger -package typealias Signposter = OSSignposter - -// -user-module-version of the 'os' module is 1062.100.1 in Xcode 16.3, which added the conformance of -// `OSSignpostIntervalState` to `Sendable` -#if !canImport(os, _version: 1062.100) -extension OSSignpostIntervalState: @retroactive @unchecked Sendable {} -#endif - -#if compiler(>=6.4) -#warning( - "Remove retroactive conformance of OSSignpostIntervalState to Sendable if we no longer need to support building SourceKit-LSP with SDKs from Xcode <16.3" -) -#endif - -extension os.Logger { - package func makeSignposter() -> Signposter { - return OSSignposter(logger: self) - } -} -#else -package typealias LogLevel = NonDarwinLogLevel -package typealias Logger = NonDarwinLogger -package typealias Signposter = NonDarwinSignposter -#endif - -/// The logger that is used to log any messages. -package var logger: Logger { - Logger(subsystem: LoggingScope.subsystem, category: LoggingScope.scope) -} diff --git a/Sources/SKLogging/LoggingScope.swift b/Sources/SKLogging/LoggingScope.swift deleted file mode 100644 index c5484c850..000000000 --- a/Sources/SKLogging/LoggingScope.swift +++ /dev/null @@ -1,93 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -package final class LoggingScope { - /// The name of the current logging subsystem or `nil` if no logging scope is set. - @TaskLocal fileprivate static var _subsystem: String? - - /// The name of the current logging scope or `nil` if no logging scope is set. - @TaskLocal fileprivate static var _scope: String? - - /// The name of the current logging subsystem. - package static var subsystem: String { - #if SKLOGGING_FOR_PLUGIN - return _subsystem ?? "org.swift.sourcekit-lsp.plugin" - #else - return _subsystem ?? "org.swift.sourcekit-lsp" - #endif - } - - /// The name of the current logging scope. - package static var scope: String { - return _scope ?? "default" - } -} - -/// Logs all messages created from the operation to the given subsystem. -/// -/// This overrides the current logging subsystem. -/// -/// - Note: Since this stores the logging subsystem in a task-local value, it only works when run inside a task. -/// Outside a task, this is a no-op. -package func withLoggingSubsystemAndScope( - subsystem: String, - scope: String?, - _ operation: @Sendable () throws -> Result -) rethrows -> Result { - return try LoggingScope.$_subsystem.withValue(subsystem) { - return try LoggingScope.$_scope.withValue(scope, operation: operation) - } -} - -/// Same as `withLoggingSubsystemAndScope` but allows the operation to be `async`. -package func withLoggingSubsystemAndScope( - subsystem: String, - scope: String?, - @_inheritActorContext _ operation: @Sendable @concurrent () async throws -> Result -) async rethrows -> Result { - return try await LoggingScope.$_subsystem.withValue(subsystem) { - return try await LoggingScope.$_scope.withValue(scope, operation: operation) - } -} - -/// Create a new logging scope, which will be used as the category in any log messages created from the operation. -/// -/// This overrides the current logging scope. -/// -/// - Note: Since this stores the logging scope in a task-local value, it only -/// works when run inside a task. Outside a task, this is a no-op. -/// - Warning: Be very careful with the dynamic creation of logging scopes. The logging scope is used as the os_log -/// category, os_log only supports 4000 different loggers and thus at most 4000 different scopes must be used. -package func withLoggingScope( - _ scope: String, - _ operation: () throws -> Result -) rethrows -> Result { - return try LoggingScope.$_scope.withValue( - scope, - operation: operation - ) -} - -/// Same as `withLoggingScope` but allows the operation to be `async`. -/// -/// - SeeAlso: ``withLoggingScope(_:_:)-6qtga`` -package func withLoggingScope( - _ scope: String, - @_inheritActorContext _ operation: @Sendable @concurrent () async throws -> Result -) async rethrows -> Result { - return try await LoggingScope.$_scope.withValue( - scope, - operation: operation - ) -} diff --git a/Sources/SKLogging/NonDarwinLogging.swift b/Sources/SKLogging/NonDarwinLogging.swift deleted file mode 100644 index 5b57f350f..000000000 --- a/Sources/SKLogging/NonDarwinLogging.swift +++ /dev/null @@ -1,449 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -package import SwiftExtensions - -#if canImport(Darwin) -import Foundation -#else -// TODO: @preconcurrency needed because stderr is not sendable on Linux https://github.com/swiftlang/swift/issues/75601 -@preconcurrency import Foundation -#endif - -// MARK: - Log settings - -package enum LogConfig { - /// The globally set log level - package static let logLevel = ThreadSafeBox( - initialValue: { - if let envVar = ProcessInfo.processInfo.environment["SOURCEKIT_LSP_LOG_LEVEL"], - let logLevel = NonDarwinLogLevel(envVar) - { - return logLevel - } - #if DEBUG - return .debug - #else - return .default - #endif - }() - ) - - /// The globally set privacy level - package static let privacyLevel = ThreadSafeBox( - initialValue: { - if let envVar = ProcessInfo.processInfo.environment["SOURCEKIT_LSP_LOG_PRIVACY_LEVEL"], - let privacyLevel = NonDarwinLogPrivacy(envVar) - { - return privacyLevel - } - #if DEBUG - return .private - #else - return .public - #endif - }() - ) -} - -/// A type that is API-compatible to `OSLogType` for all uses within -/// sourcekit-lsp. -/// -/// This is used on platforms that don't have OSLog. -/// -/// For documentation of the different log levels see -/// https://developer.apple.com/documentation/os/oslogtype. -package enum NonDarwinLogLevel: Comparable, CustomStringConvertible, Sendable { - case debug - case info - case `default` - case error - case fault - - package init?(_ value: String) { - switch value.lowercased() { - case "debug": self = .debug - case "info": self = .info - case "default": self = .`default` - case "error": self = .error - case "fault": self = .fault - default: - if let int = Int(value) { - self.init(int) - } else { - return nil - } - } - } - - package init?(_ value: Int) { - switch value { - case 0: self = .fault - case 1: self = .error - case 2: self = .default - case 3: self = .info - case 4: self = .debug - default: return nil - } - } - - package var description: String { - switch self { - case .debug: - return "debug" - case .info: - return "info" - case .default: - return "default" - case .error: - return "error" - case .fault: - return "fault" - } - } -} - -/// A type that is API-compatible to `OSLogPrivacy` for all uses within -/// sourcekit-lsp. -/// -/// This is used on platforms that don't have OSLog. -/// -/// For documentation of the different privacy levels see -/// https://developer.apple.com/documentation/os/oslogprivacy. -package enum NonDarwinLogPrivacy: Comparable, Sendable { - case `public` - case `private` - case sensitive - - package init?(_ value: String) { - switch value.lowercased() { - case "sensitive": self = .sensitive - case "private": self = .private - case "public": self = .public - default: return nil - } - } -} - -// MARK: String interpolation - -/// A type that is API-compatible to `OSLogInterpolation` for all uses within -/// sourcekit-lsp. -/// -/// This is used on platforms that don't have OSLog. -package struct NonDarwinLogInterpolation: StringInterpolationProtocol, Sendable { - private enum LogPiece: Sendable { - /// A segment of the log message that will always be displayed. - case string(String) - - /// A segment of the log message that might need to be redacted if the - /// privacy level is lower than `privacy`. - case possiblyRedacted( - description: @Sendable () -> String, - redactedDescription: @Sendable () -> String, - privacy: NonDarwinLogPrivacy - ) - } - - private var pieces: [LogPiece] - - package init(literalCapacity: Int, interpolationCount: Int) { - self.pieces = [] - pieces.reserveCapacity(literalCapacity + interpolationCount) - } - - package mutating func appendLiteral(_ literal: String) { - pieces.append(.string(literal)) - } - - private mutating func append( - description: @autoclosure @escaping @Sendable () -> String, - redactedDescription: @autoclosure @escaping @Sendable () -> String, - privacy: NonDarwinLogPrivacy - ) { - if privacy == .public { - // We are always logging the description. No need to store the redacted description as well. - pieces.append(.string(description())) - } else { - pieces.append( - .possiblyRedacted( - description: description, - redactedDescription: redactedDescription, - privacy: privacy - ) - ) - } - } - - package mutating func appendInterpolation(_ message: StaticString, privacy: NonDarwinLogPrivacy = .public) { - append(description: message.description, redactedDescription: "", privacy: privacy) - } - - @_disfavoredOverload // Prefer to use the StaticString overload when possible. - package mutating func appendInterpolation( - _ message: some CustomStringConvertible & Sendable, - privacy: NonDarwinLogPrivacy = .private - ) { - append(description: message.description, redactedDescription: "", privacy: privacy) - } - - package mutating func appendInterpolation( - _ message: some CustomLogStringConvertibleWrapper & Sendable, - privacy: NonDarwinLogPrivacy = .private - ) { - append(description: message.description, redactedDescription: message.redactedDescription, privacy: privacy) - } - - package mutating func appendInterpolation( - _ message: (some CustomLogStringConvertibleWrapper & Sendable)?, - privacy: NonDarwinLogPrivacy = .private - ) { - if let message { - self.appendInterpolation(message, privacy: privacy) - } else { - self.appendLiteral("") - } - } - - package mutating func appendInterpolation(_ type: Any.Type, privacy: NonDarwinLogPrivacy = .public) { - append(description: String(reflecting: type), redactedDescription: "", privacy: privacy) - } - - package mutating func appendInterpolation( - _ message: some Numeric & Sendable, - privacy: NonDarwinLogPrivacy = .public - ) { - append(description: String(describing: message), redactedDescription: "", privacy: privacy) - } - - package mutating func appendInterpolation(_ message: Bool, privacy: NonDarwinLogPrivacy = .public) { - append(description: message.description, redactedDescription: "", privacy: privacy) - } - - /// Builds the string that represents the log message, masking all interpolation - /// segments whose privacy level is greater that `logPrivacyLevel`. - fileprivate func string(for logPrivacyLevel: NonDarwinLogPrivacy) -> String { - var result = "" - for piece in pieces { - switch piece { - case .string(let string): - result += string - case .possiblyRedacted(let description, redactedDescription: let redacted, let privacy): - if privacy > logPrivacyLevel { - result += redacted() - } else { - result += description() - } - } - } - return result - } -} - -/// A type that is API-compatible to `OSLogMessage` for all uses within -/// sourcekit-lsp. -/// -/// This is used on platforms that don't have OSLog. -package struct NonDarwinLogMessage: ExpressibleByStringInterpolation, ExpressibleByStringLiteral, Sendable { - fileprivate let value: NonDarwinLogInterpolation - - package init(stringInterpolation: NonDarwinLogInterpolation) { - self.value = stringInterpolation - } - - package init(stringLiteral value: String) { - var interpolation = NonDarwinLogInterpolation(literalCapacity: 1, interpolationCount: 0) - interpolation.appendLiteral(value) - self.value = interpolation - } -} - -// MARK: - Logger - -/// The formatter used to format dates in log messages. -/// -/// A global variable because we frequently create new loggers, the creation of -/// a new `DateFormatter` is rather expensive and its the same for all loggers. -private let dateFormatter = { - let dateFormatter = DateFormatter() - dateFormatter.timeZone = NSTimeZone.local - dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS Z" - return dateFormatter -}() - -/// Actor that protects `logHandler` -@globalActor -actor LogHandlerActor { - static let shared: LogHandlerActor = LogHandlerActor() -} - -/// The handler that is called to log a message from `NonDarwinLogger` unless `overrideLogHandler` is set on the logger. -@LogHandlerActor -var logHandler: @Sendable (String) async -> Void = { fputs($0 + "\n", stderr) } - -/// The queue on which we log messages. -/// -/// A global queue since we create and discard loggers all the time. -private let loggingQueue = AsyncQueue() - -/// A logger that is designed to be API-compatible with `os.Logger` for all uses -/// in sourcekit-lsp. -/// -/// This logger is used to log messages to stderr on platforms where OSLog is -/// not available. -/// -/// `overrideLogHandler` allows capturing of the logged messages for testing purposes. -package struct NonDarwinLogger: Sendable { - private let subsystem: String - private let category: String - private let logLevel: NonDarwinLogLevel - fileprivate let privacyLevel: NonDarwinLogPrivacy - private let overrideLogHandler: (@Sendable (String) -> Void)? - - /// - Parameters: - /// - subsystem: See os.Logger - /// - category: See os.Logger - /// - logLevel: The level to log at. All messages with a lower log level - /// will be ignored - /// - privacyLevel: The privacy level to log at. Any interpolation segments - /// with a higher privacy level will be masked. - /// - logHandler: The function that actually logs the message. - package init( - subsystem: String, - category: String, - logLevel: NonDarwinLogLevel? = nil, - privacyLevel: NonDarwinLogPrivacy? = nil, - overrideLogHandler: (@Sendable (String) -> Void)? = nil - ) { - self.subsystem = subsystem - self.category = category - self.logLevel = logLevel ?? LogConfig.logLevel.value - self.privacyLevel = privacyLevel ?? LogConfig.privacyLevel.value - self.overrideLogHandler = overrideLogHandler - } - - /// Logs the given message at the given level. - /// - /// Logging is performed asynchronously to allow the execution of the main - /// program to finish as quickly as possible. - package func log( - level: NonDarwinLogLevel, - _ message: @autoclosure @escaping @Sendable () -> NonDarwinLogMessage - ) { - guard level >= self.logLevel else { return } - let date = Date() - loggingQueue.async(priority: .utility) { @LogHandlerActor in - // Truncate log message after 10.000 characters to avoid flooding the log with huge log messages (eg. from a - // sourcekitd response). 10.000 characters was chosen because it seems to fit the result of most sourcekitd - // responses that are not generated interface or global completion results (which are a lot bigger). - var message = message().value.string(for: self.privacyLevel) - if message.utf8.count > 10_000 { - // Check for UTF-8 byte length first because that's faster since it doesn't need to count UTF-8 characters. - // Truncate using `.prefix` to avoid cutting of in the middle of a UTF-8 multi-byte character. - message = message.prefix(10_000) + "..." - } - // Start each log message with `[org.swift.sourcekit-lsp` so that it’s easy to split the log to the different messages - await (overrideLogHandler ?? logHandler)( - """ - [\(subsystem):\(category)] \(level) \(dateFormatter.string(from: date)) - \(message) - --- - """ - ) - } - } - - /// Log a message at the `debug` level. - package func debug(_ message: NonDarwinLogMessage) { - log(level: .debug, message) - } - - /// Log a message at the `info` level. - package func info(_ message: NonDarwinLogMessage) { - log(level: .info, message) - } - - /// Log a message at the `default` level. - package func log(_ message: NonDarwinLogMessage) { - log(level: .default, message) - } - - /// Log a message at the `error` level. - package func error(_ message: NonDarwinLogMessage) { - log(level: .error, message) - } - - /// Log a message at the `fault` level. - package func fault(_ message: NonDarwinLogMessage) { - log(level: .fault, message) - } - - /// Wait for all log messages to be written. - /// - /// Useful for testing to make sure all asynchronous log calls have actually - /// written their data. - package static func flush() async { - await loggingQueue.async {}.value - } - - package func makeSignposter() -> NonDarwinSignposter { - return NonDarwinSignposter(logger: self) - } -} - -// MARK: - Signposter - -package struct NonDarwinSignpostID: Sendable { - fileprivate let id: UInt32 -} - -package struct NonDarwinSignpostIntervalState: Sendable { - fileprivate let id: NonDarwinSignpostID -} - -private let nextSignpostID = AtomicUInt32(initialValue: 0) - -/// A type that is API-compatible to `OSLogMessage` for all uses within sourcekit-lsp. -/// -/// Since non-Darwin platforms don't have signposts, the type just has no-op operations. -package struct NonDarwinSignposter: Sendable { - private let logger: NonDarwinLogger - - fileprivate init(logger: NonDarwinLogger) { - self.logger = logger - } - - package func makeSignpostID() -> NonDarwinSignpostID { - return NonDarwinSignpostID(id: nextSignpostID.fetchAndIncrement()) - } - - package func beginInterval( - _ name: StaticString, - id: NonDarwinSignpostID, - _ message: NonDarwinLogMessage - ) -> NonDarwinSignpostIntervalState { - logger.log(level: .debug, "Signpost \(id.id) begin: \(name) - \(message.value.string(for: logger.privacyLevel))") - return NonDarwinSignpostIntervalState(id: id) - } - - package func emitEvent(_ name: StaticString, id: NonDarwinSignpostID, _ message: NonDarwinLogMessage = "") { - logger.log(level: .debug, "Signpost \(id.id) event: \(name) - \(message.value.string(for: logger.privacyLevel))") - } - - package func endInterval( - _ name: StaticString, - _ state: NonDarwinSignpostIntervalState, - _ message: StaticString = "" - ) { - logger.log(level: .debug, "Signpost \(state.id.id) end: \(name) - \(message)") - } -} diff --git a/Sources/SKLogging/OrLog.swift b/Sources/SKLogging/OrLog.swift deleted file mode 100644 index d8dbdf17e..000000000 --- a/Sources/SKLogging/OrLog.swift +++ /dev/null @@ -1,52 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -#if canImport(os) -import os -#endif - -private func logError(prefix: String, error: Error, level: LogLevel = .error) { - logger.log( - level: level, - "\(prefix, privacy: .public)\(prefix.isEmpty ? "" : ": ", privacy: .public)\(error.forLogging)" - ) -} - -/// Like `try?`, but logs the error on failure. -package func orLog( - _ prefix: @autoclosure () -> String, - level: LogLevel = .error, - _ block: () throws -> R? -) -> R? { - do { - return try block() - } catch { - logError(prefix: prefix(), error: error, level: level) - return nil - } -} - -/// Like ``orLog(_:level:_:)-66i2z`` but allows execution of an `async` body. -/// -/// - SeeAlso: ``orLog(_:level:_:)-66i2z`` -package func orLog( - _ prefix: @autoclosure () -> String, - level: LogLevel = .error, - _ block: () async throws -> R? -) async -> R? { - do { - return try await block() - } catch { - logError(prefix: prefix(), error: error, level: level) - return nil - } -} diff --git a/Sources/SKLogging/SetGlobalLogFileHandler.swift b/Sources/SKLogging/SetGlobalLogFileHandler.swift deleted file mode 100644 index 2b2ea8a87..000000000 --- a/Sources/SKLogging/SetGlobalLogFileHandler.swift +++ /dev/null @@ -1,200 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import RegexBuilder -import SwiftExtensions - -#if canImport(Darwin) -package import Foundation -#else -// TODO: @preconcurrency needed because stderr is not sendable on Linux https://github.com/swiftlang/swift/issues/75601 -@preconcurrency package import Foundation -#endif - -#if os(Windows) -import WinSDK -#endif - -#if !canImport(os) || SOURCEKIT_LSP_FORCE_NON_DARWIN_LOGGER -/// The number of log file handles that have been created by this process. -/// -/// See comment on `logFileHandle`. -@LogHandlerActor -private var logRotateIndex = 0 - -/// The file handle to the current log file. When the file managed by this handle reaches its maximum size, we increment -/// the `logRotateIndex` by 1 and set the `logFileHandle` to `nil`. This causes a new log file handle with index -/// `logRotateIndex % logRotateCount` to be created on the next log call. -@LogHandlerActor -private var logFileHandle: FileHandle? - -@LogHandlerActor -func getOrCreateLogFileHandle(logDirectory: URL, logRotateCount: Int) -> FileHandle { - if let logFileHandle { - return logFileHandle - } - - // Name must match the regex in `cleanOldLogFiles` and the prefix in `DiagnoseCommand.addNonDarwinLogs`. - let logFileUrl = logDirectory.appending( - component: - "sourcekit-lsp-\(ProcessInfo.processInfo.processIdentifier).\(logRotateIndex % logRotateCount).log" - ) - - do { - try FileManager.default.createDirectory(at: logDirectory, withIntermediateDirectories: true) - if !FileManager.default.fileExists(at: logFileUrl) { - try FileManager.default.createFile(at: logFileUrl, contents: nil) - } - let newFileHandle = try FileHandle(forWritingTo: logFileUrl) - logFileHandle = newFileHandle - try newFileHandle.truncate(atOffset: 0) - return newFileHandle - } catch { - // If we fail to create a file handle for the log file, log one message about it to stderr and then log to stderr. - // We will try creating a log file again once this section of the log reaches `maxLogFileSize` but that means that - // we'll only log this error every `maxLogFileSize` bytes, which is a lot less spammy than logging it on every log - // call. - fputs("Failed to open file handle for log file at \(logFileUrl): \(error)", stderr) - logFileHandle = FileHandle.standardError - return FileHandle.standardError - } -} - -/// Log the given message to a log file in the given log directory. -/// -/// The name of the log file includes the PID of the current process to make sure it is exclusively writing to the file. -/// When a log file reaches `logFileMaxBytes`, it will be rotated, with at most `logRotateCount` different log files -/// being created. -@LogHandlerActor -private func logToFile(message: String, logDirectory: URL, logFileMaxBytes: Int, logRotateCount: Int) throws { - - guard let data = message.data(using: .utf8) else { - fputs( - """ - Failed to convert log message to UTF-8 data - \(message) - - """, - stderr - ) - return - } - let logFileHandleUnwrapped = getOrCreateLogFileHandle(logDirectory: logDirectory, logRotateCount: logRotateCount) - try logFileHandleUnwrapped.write(contentsOf: data) - - // If this log file has exceeded the maximum size, start writing to a new log file. - if try logFileHandleUnwrapped.offset() > logFileMaxBytes { - logRotateIndex += 1 - // Resetting `logFileHandle` will cause a new logFileHandle to be created on the next log call. - logFileHandle = nil - } -} - -/// If the file at the given path is writable, redirect log messages handled by `NonDarwinLogHandler` to the given file. -/// -/// Occasionally checks that the log does not exceed `targetLogSize` (in bytes) and truncates the beginning of the log -/// when it does. -@LogHandlerActor -private func setUpGlobalLogFileHandlerImpl(logFileDirectory: URL, logFileMaxBytes: Int, logRotateCount: Int) { - logHandler = { @LogHandlerActor message in - do { - try logToFile( - message: message, - logDirectory: logFileDirectory, - logFileMaxBytes: logFileMaxBytes, - logRotateCount: logRotateCount - ) - } catch { - fputs( - """ - Failed to write message to log file: \(error) - \(message) - - """, - stderr - ) - } - } -} - -/// Returns `true` if a process with the given PID still exists and is alive. -private func isProcessAlive(pid: Int32) -> Bool { - #if os(Windows) - if let handle = OpenProcess(UInt32(PROCESS_QUERY_INFORMATION), /*bInheritHandle=*/ false, UInt32(pid)) { - CloseHandle(handle) - return true - } - return false - #else - return kill(pid, 0) == 0 // ignore-unacceptable-language - #endif -} - -private func cleanOldLogFilesImpl(logFileDirectory: URL, maxAge: TimeInterval) { - let enumerator = FileManager.default.enumerator(at: logFileDirectory, includingPropertiesForKeys: nil) - while let url = enumerator?.nextObject() as? URL { - let name = url.lastPathComponent - let regex = Regex { - "sourcekit-lsp-" - Capture(ZeroOrMore(.digit)) - "." - ZeroOrMore(.digit) - ".log" - } - guard let match = name.matches(of: regex).only, let pid = Int32(match.1) else { - continue - } - if isProcessAlive(pid: pid) { - // Process that owns this log file is still alive. Don't delete it. - continue - } - guard - let modificationDate = orLog( - "Getting mtime of old log file", - { try FileManager.default.attributesOfItem(atPath: url.filePath)[.modificationDate] } - ) as? Date, - Date().timeIntervalSince(modificationDate) > maxAge - else { - // File has been modified in the last hour. Don't delete it because it's useful to diagnose issues after - // sourcekit-lsp has exited. - continue - } - orLog("Deleting old log file") { try FileManager.default.removeItem(at: url) } - } -} -#endif - -/// If the file at the given path is writable, redirect log messages handled by `NonDarwinLogHandler` to the given file. -/// -/// Occasionally checks that the log does not exceed `targetLogSize` (in bytes) and truncates the beginning of the log -/// when it does. -/// -/// No-op when using OSLog. -package func setUpGlobalLogFileHandler(logFileDirectory: URL, logFileMaxBytes: Int, logRotateCount: Int) async { - #if !canImport(os) || SOURCEKIT_LSP_FORCE_NON_DARWIN_LOGGER - await setUpGlobalLogFileHandlerImpl( - logFileDirectory: logFileDirectory, - logFileMaxBytes: logFileMaxBytes, - logRotateCount: logRotateCount - ) - #endif -} - -/// Deletes all sourcekit-lsp log files in `logFilesDirectory` that are not associated with a running process and that -/// haven't been modified within the last hour. -/// -/// No-op when using OSLog. -package func cleanOldLogFiles(logFileDirectory: URL, maxAge: TimeInterval) { - #if !canImport(os) || SOURCEKIT_LSP_FORCE_NON_DARWIN_LOGGER - cleanOldLogFilesImpl(logFileDirectory: logFileDirectory, maxAge: maxAge) - #endif -} diff --git a/Sources/SKLogging/SplitLogMessage.swift b/Sources/SKLogging/SplitLogMessage.swift deleted file mode 100644 index e6bd5e5c9..000000000 --- a/Sources/SKLogging/SplitLogMessage.swift +++ /dev/null @@ -1,68 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Splits `message` on newline characters such that each chunk is at most `maxChunkSize` bytes long. -/// -/// The intended use case for this is to split compiler arguments and a file's contents into multiple chunks so -/// that each chunk doesn't exceed the maximum message length of `os_log` and thus won't get truncated. -/// -/// - Note: This will only split along newline boundary. If a single line is longer than `maxChunkSize`, it won't be -/// split. This is fine for compiler argument splitting since a single argument is rarely longer than 800 characters. -package func splitLongMultilineMessage(message: String) -> [String] { - let maxChunkSize = 800 - var chunks: [String] = [] - for line in message.split(separator: "\n", omittingEmptySubsequences: false) { - if let lastChunk = chunks.last, lastChunk.utf8.count + line.utf8.count < maxChunkSize { - chunks[chunks.count - 1] += "\n" + line - } else { - if !chunks.isEmpty { - // Append an end marker to the last chunk so that os_log doesn't truncate trailing whitespace, - // which would modify the source contents. - // Empty newlines are important so the offset of the request is correct. - chunks[chunks.count - 1] += "\n--- End Chunk" - } - chunks.append(String(line)) - } - } - return chunks -} - -extension Logger { - /// Implementation detail of `logFullObjectInMultipleLogMessages` - private struct LoggableChunk: CustomLogStringConvertible { - var description: String - var redactedDescription: String - } - - package func logFullObjectInMultipleLogMessages( - level: LogLevel = .default, - header: StaticString, - _ subject: some CustomLogStringConvertible - ) { - let chunks = splitLongMultilineMessage(message: subject.description) - let redactedChunks = splitLongMultilineMessage(message: subject.redactedDescription) - let maxChunkCount = max(chunks.count, redactedChunks.count) - for i in 0..>:Foundation>) add_library(SKUtilitiesForPlugin STATIC ${sources}) @@ -18,10 +19,12 @@ set_target_properties(SKUtilitiesForPlugin PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_compile_options(SKUtilitiesForPlugin PRIVATE $<$: - "SHELL:-module-alias SKLogging=SKLoggingForPlugin" + "SHELL:-module-alias SKLogging=_SKLoggingForPlugin" "SHELL:-module-alias SwiftExtensions=SwiftExtensionsForPlugin" + "SHELL:-module-alias ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin" >) target_link_libraries(SKUtilitiesForPlugin PRIVATE - SKLoggingForPlugin + SwiftToolsProtocols::_SKLoggingForPlugin SwiftExtensionsForPlugin + SwiftToolsProtocols::_ToolsProtocolsSwiftExtensionsForPlugin $<$>:Foundation>) diff --git a/Sources/SKUtilities/Dictionary+InitWithElementsKeyedBy.swift b/Sources/SKUtilities/Dictionary+InitWithElementsKeyedBy.swift index 223b106fc..8ecd05707 100644 --- a/Sources/SKUtilities/Dictionary+InitWithElementsKeyedBy.swift +++ b/Sources/SKUtilities/Dictionary+InitWithElementsKeyedBy.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import SKLogging +@_spi(SourceKitLSP) import SKLogging extension Dictionary { /// Create a new dictionary from the given elements, assuming that they all have a unique value identified by `keyedBy`. diff --git a/Sources/SKUtilities/LineTable.swift b/Sources/SKUtilities/LineTable.swift index 4e5ac8413..25ee300c9 100644 --- a/Sources/SKUtilities/LineTable.swift +++ b/Sources/SKUtilities/LineTable.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import SKLogging +@_spi(SourceKitLSP) import SKLogging #if canImport(os) import os diff --git a/Sources/SemanticIndex/CMakeLists.txt b/Sources/SemanticIndex/CMakeLists.txt index 6f72105cd..2663c3c76 100644 --- a/Sources/SemanticIndex/CMakeLists.txt +++ b/Sources/SemanticIndex/CMakeLists.txt @@ -13,9 +13,10 @@ set_target_properties(SemanticIndex PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(SemanticIndex PRIVATE BuildServerIntegration - LanguageServerProtocol - SKLogging + SwiftToolsProtocols::LanguageServerProtocol + SwiftToolsProtocols::SKLogging SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions ToolchainRegistry TSCExtensions IndexStoreDB diff --git a/Sources/SemanticIndex/CheckedIndex.swift b/Sources/SemanticIndex/CheckedIndex.swift index 4077cb482..f7d27f61f 100644 --- a/Sources/SemanticIndex/CheckedIndex.swift +++ b/Sources/SemanticIndex/CheckedIndex.swift @@ -13,8 +13,8 @@ package import BuildServerIntegration package import Foundation @preconcurrency package import IndexStoreDB -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions /// Essentially a `DocumentManager` from the `SourceKitLSP` module. diff --git a/Sources/SemanticIndex/IndexTaskDescription.swift b/Sources/SemanticIndex/IndexTaskDescription.swift index d687561ec..43ce91df0 100644 --- a/Sources/SemanticIndex/IndexTaskDescription.swift +++ b/Sources/SemanticIndex/IndexTaskDescription.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import SKLogging +@_spi(SourceKitLSP) import SKLogging /// Protocol of tasks that are executed on the index task scheduler. /// diff --git a/Sources/SemanticIndex/PreparationTaskDescription.swift b/Sources/SemanticIndex/PreparationTaskDescription.swift index 5e5d932b1..664f0abe0 100644 --- a/Sources/SemanticIndex/PreparationTaskDescription.swift +++ b/Sources/SemanticIndex/PreparationTaskDescription.swift @@ -11,12 +11,13 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import class TSCBasic.Process diff --git a/Sources/SemanticIndex/SemanticIndexManager.swift b/Sources/SemanticIndex/SemanticIndexManager.swift index 49c43bae1..c0202e6cf 100644 --- a/Sources/SemanticIndex/SemanticIndexManager.swift +++ b/Sources/SemanticIndex/SemanticIndexManager.swift @@ -11,12 +11,13 @@ //===----------------------------------------------------------------------===// package import BuildServerIntegration -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// The logging subsystem that should be used for all index-related logging. let indexLoggingSubsystem = "org.swift.sourcekit-lsp.indexing" diff --git a/Sources/SemanticIndex/TaskScheduler.swift b/Sources/SemanticIndex/TaskScheduler.swift index b50dcbfd7..796a90348 100644 --- a/Sources/SemanticIndex/TaskScheduler.swift +++ b/Sources/SemanticIndex/TaskScheduler.swift @@ -11,9 +11,10 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocolExtensions -package import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// See comment on ``TaskDescriptionProtocol/dependencies(to:taskPriority:)`` package enum TaskDependencyAction { diff --git a/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift b/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift index 0d6b91e00..af170b2fb 100644 --- a/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift +++ b/Sources/SemanticIndex/UpdateIndexStoreTaskDescription.swift @@ -11,14 +11,15 @@ //===----------------------------------------------------------------------===// package import BuildServerIntegration -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions import TSCExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import class TSCBasic.Process diff --git a/Sources/SourceKitD/CMakeLists.txt b/Sources/SourceKitD/CMakeLists.txt index 3fad8d47a..51fd199cc 100644 --- a/Sources/SourceKitD/CMakeLists.txt +++ b/Sources/SourceKitD/CMakeLists.txt @@ -16,8 +16,9 @@ set_target_properties(SourceKitD PROPERTIES target_link_libraries(SourceKitD PUBLIC Csourcekitd) target_link_libraries(SourceKitD PRIVATE - SKLogging + SwiftToolsProtocols::SKLogging SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions $<$>:Foundation>) @@ -26,12 +27,14 @@ set_target_properties(SourceKitDForPlugin PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_compile_options(SourceKitDForPlugin PRIVATE $<$: - "SHELL:-module-alias SKLogging=SKLoggingForPlugin" + "SHELL:-module-alias SKLogging=_SKLoggingForPlugin" "SHELL:-module-alias SwiftExtensions=SwiftExtensionsForPlugin" + "SHELL:-module-alias ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin" >) target_link_libraries(SourceKitDForPlugin PUBLIC Csourcekitd) target_link_libraries(SourceKitDForPlugin PRIVATE - SKLoggingForPlugin + SwiftToolsProtocols::_SKLoggingForPlugin SwiftExtensionsForPlugin + SwiftToolsProtocols::_ToolsProtocolsSwiftExtensionsForPlugin $<$>:Foundation>) diff --git a/Sources/SourceKitD/SKDRequestDictionary.swift b/Sources/SourceKitD/SKDRequestDictionary.swift index 6ae563766..c1504f348 100644 --- a/Sources/SourceKitD/SKDRequestDictionary.swift +++ b/Sources/SourceKitD/SKDRequestDictionary.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Csourcekitd -import SKLogging +@_spi(SourceKitLSP) import SKLogging #if canImport(Darwin) import Darwin diff --git a/Sources/SourceKitD/SKDResponse.swift b/Sources/SourceKitD/SKDResponse.swift index a7a290f15..b3a95b4ad 100644 --- a/Sources/SourceKitD/SKDResponse.swift +++ b/Sources/SourceKitD/SKDResponse.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Csourcekitd -import SKLogging +@_spi(SourceKitLSP) import SKLogging #if canImport(Darwin) import Darwin diff --git a/Sources/SourceKitD/SourceKitD.swift b/Sources/SourceKitD/SourceKitD.swift index f76c0e34b..56785f2a2 100644 --- a/Sources/SourceKitD/SourceKitD.swift +++ b/Sources/SourceKitD/SourceKitD.swift @@ -12,8 +12,9 @@ package import Csourcekitd package import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions extension sourcekitd_api_keys: @unchecked Sendable {} extension sourcekitd_api_requests: @unchecked Sendable {} diff --git a/Sources/SourceKitD/SourceKitDRegistry.swift b/Sources/SourceKitD/SourceKitDRegistry.swift index f67e3a437..22c8a66e8 100644 --- a/Sources/SourceKitD/SourceKitDRegistry.swift +++ b/Sources/SourceKitD/SourceKitDRegistry.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging /// The set of known SourceKitD instances, uniqued by path. /// diff --git a/Sources/SourceKitD/dlopen.swift b/Sources/SourceKitD/dlopen.swift index dd34e4f97..f03d8fc24 100644 --- a/Sources/SourceKitD/dlopen.swift +++ b/Sources/SourceKitD/dlopen.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions #if os(Windows) diff --git a/Sources/SourceKitLSP/CMakeLists.txt b/Sources/SourceKitLSP/CMakeLists.txt index 7b9677fff..74d04c9ab 100644 --- a/Sources/SourceKitLSP/CMakeLists.txt +++ b/Sources/SourceKitLSP/CMakeLists.txt @@ -31,21 +31,22 @@ set_target_properties(SourceKitLSP PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY} ) target_link_libraries(SourceKitLSP PUBLIC - BuildServerProtocol + SwiftToolsProtocols::BuildServerProtocol BuildServerIntegration - LanguageServerProtocol + SwiftToolsProtocols::LanguageServerProtocol LanguageServerProtocolExtensions SemanticIndex SKOptions SKUtilities SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions ToolchainRegistry IndexStoreDB SwiftSyntax::SwiftSyntax ) target_link_libraries(SourceKitLSP PRIVATE - LanguageServerProtocolJSONRPC - SKLogging + SwiftToolsProtocols::LanguageServerProtocolTransport + SwiftToolsProtocols::SKLogging SourceKitD TSCExtensions $<$>:FoundationXML> diff --git a/Sources/SourceKitLSP/CapabilityRegistry.swift b/Sources/SourceKitLSP/CapabilityRegistry.swift index 319500ab2..27fdb15cc 100644 --- a/Sources/SourceKitLSP/CapabilityRegistry.swift +++ b/Sources/SourceKitLSP/CapabilityRegistry.swift @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions /// A class which tracks the client's capabilities as well as our dynamic diff --git a/Sources/SourceKitLSP/DocumentManager.swift b/Sources/SourceKitLSP/DocumentManager.swift index f06522749..91055cd32 100644 --- a/Sources/SourceKitLSP/DocumentManager.swift +++ b/Sources/SourceKitLSP/DocumentManager.swift @@ -12,8 +12,8 @@ import Dispatch import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging package import SKUtilities import SemanticIndex package import SwiftSyntax diff --git a/Sources/SourceKitLSP/DocumentSnapshot+FromFileContents.swift b/Sources/SourceKitLSP/DocumentSnapshot+FromFileContents.swift index 9bbb62493..61410bfd4 100644 --- a/Sources/SourceKitLSP/DocumentSnapshot+FromFileContents.swift +++ b/Sources/SourceKitLSP/DocumentSnapshot+FromFileContents.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SKUtilities package extension DocumentSnapshot { diff --git a/Sources/SourceKitLSP/DocumentSnapshot+PositionConversions.swift b/Sources/SourceKitLSP/DocumentSnapshot+PositionConversions.swift index b8df99d9d..7d881ce6b 100644 --- a/Sources/SourceKitLSP/DocumentSnapshot+PositionConversions.swift +++ b/Sources/SourceKitLSP/DocumentSnapshot+PositionConversions.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// package import IndexStoreDB -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities package import SwiftSyntax diff --git a/Sources/SourceKitLSP/GeneratedInterfaceDocumentURLData.swift b/Sources/SourceKitLSP/GeneratedInterfaceDocumentURLData.swift index 275a12b1d..eb7eda428 100644 --- a/Sources/SourceKitLSP/GeneratedInterfaceDocumentURLData.swift +++ b/Sources/SourceKitLSP/GeneratedInterfaceDocumentURLData.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol /// Represents url of generated interface reference document. package struct GeneratedInterfaceDocumentURLData: Hashable, ReferenceURLData { diff --git a/Sources/SourceKitLSP/Hooks.swift b/Sources/SourceKitLSP/Hooks.swift index e614fd974..96cf0f021 100644 --- a/Sources/SourceKitLSP/Hooks.swift +++ b/Sources/SourceKitLSP/Hooks.swift @@ -12,8 +12,8 @@ package import BuildServerIntegration import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions package import SemanticIndex import struct TSCBasic.AbsolutePath diff --git a/Sources/SourceKitLSP/IndexProgressManager.swift b/Sources/SourceKitLSP/IndexProgressManager.swift index 2d9e89666..f5b2fb62e 100644 --- a/Sources/SourceKitLSP/IndexProgressManager.swift +++ b/Sources/SourceKitLSP/IndexProgressManager.swift @@ -10,12 +10,13 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions import SemanticIndex import SwiftExtensions +import ToolsProtocolsSwiftExtensions /// Listens for index status updates from `SemanticIndexManagers`. From that information, it manages a /// `WorkDoneProgress` that communicates the index progress to the editor. diff --git a/Sources/SourceKitLSP/IndexStoreDB+MainFilesProvider.swift b/Sources/SourceKitLSP/IndexStoreDB+MainFilesProvider.swift index a879c0f23..ed81416dd 100644 --- a/Sources/SourceKitLSP/IndexStoreDB+MainFilesProvider.swift +++ b/Sources/SourceKitLSP/IndexStoreDB+MainFilesProvider.swift @@ -13,8 +13,8 @@ import BuildServerIntegration import Foundation import IndexStoreDB -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SemanticIndex import SwiftExtensions diff --git a/Sources/SourceKitLSP/LanguageService.swift b/Sources/SourceKitLSP/LanguageService.swift index 453503d8f..b251ce15b 100644 --- a/Sources/SourceKitLSP/LanguageService.swift +++ b/Sources/SourceKitLSP/LanguageService.swift @@ -13,8 +13,8 @@ package import BuildServerIntegration import Foundation package import IndexStoreDB -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging package import SKOptions package import SwiftSyntax package import ToolchainRegistry diff --git a/Sources/SourceKitLSP/LanguageServiceRegistry.swift b/Sources/SourceKitLSP/LanguageServiceRegistry.swift index b591d3ae9..1ab81505e 100644 --- a/Sources/SourceKitLSP/LanguageServiceRegistry.swift +++ b/Sources/SourceKitLSP/LanguageServiceRegistry.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import IndexStoreDB -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging /// Wrapper around `LanguageService.Type`, making it conform to `Hashable`. struct LanguageServiceType: Hashable { diff --git a/Sources/SourceKitLSP/LogMessageNotification+representingStructureUsingEmojiPrefixIfNecessary.swift b/Sources/SourceKitLSP/LogMessageNotification+representingStructureUsingEmojiPrefixIfNecessary.swift index 0fa20b780..a1bd75c8e 100644 --- a/Sources/SourceKitLSP/LogMessageNotification+representingStructureUsingEmojiPrefixIfNecessary.swift +++ b/Sources/SourceKitLSP/LogMessageNotification+representingStructureUsingEmojiPrefixIfNecessary.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SKOptions import struct TSCBasic.ProcessResult diff --git a/Sources/SourceKitLSP/MacroExpansionReferenceDocumentURLData.swift b/Sources/SourceKitLSP/MacroExpansionReferenceDocumentURLData.swift index eb114bf36..4070f5754 100644 --- a/Sources/SourceKitLSP/MacroExpansionReferenceDocumentURLData.swift +++ b/Sources/SourceKitLSP/MacroExpansionReferenceDocumentURLData.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// package import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import RegexBuilder /// Represents url of macro expansion reference document as follows: diff --git a/Sources/SourceKitLSP/MessageHandlingDependencyTracker.swift b/Sources/SourceKitLSP/MessageHandlingDependencyTracker.swift index 9c2839ff0..7adca4809 100644 --- a/Sources/SourceKitLSP/MessageHandlingDependencyTracker.swift +++ b/Sources/SourceKitLSP/MessageHandlingDependencyTracker.swift @@ -10,10 +10,12 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// A lightweight way of describing tasks that are created from handling LSP /// requests or notifications for the purpose of dependency tracking. diff --git a/Sources/SourceKitLSP/OnDiskDocumentManager.swift b/Sources/SourceKitLSP/OnDiskDocumentManager.swift index f66610e05..f67832647 100644 --- a/Sources/SourceKitLSP/OnDiskDocumentManager.swift +++ b/Sources/SourceKitLSP/OnDiskDocumentManager.swift @@ -12,8 +12,8 @@ package import BuildServerIntegration import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SwiftExtensions diff --git a/Sources/SourceKitLSP/ReferenceDocumentURL.swift b/Sources/SourceKitLSP/ReferenceDocumentURL.swift index 11ed7adff..351d2551e 100644 --- a/Sources/SourceKitLSP/ReferenceDocumentURL.swift +++ b/Sources/SourceKitLSP/ReferenceDocumentURL.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol protocol ReferenceURLData { static var documentType: String { get } diff --git a/Sources/SourceKitLSP/Rename.swift b/Sources/SourceKitLSP/Rename.swift index b61506d77..7c5997c32 100644 --- a/Sources/SourceKitLSP/Rename.swift +++ b/Sources/SourceKitLSP/Rename.swift @@ -11,11 +11,12 @@ //===----------------------------------------------------------------------===// package import IndexStoreDB -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SemanticIndex import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions // MARK: - Helper types diff --git a/Sources/SourceKitLSP/SemanticTokensLegend+SourceKitLSPLegend.swift b/Sources/SourceKitLSP/SemanticTokensLegend+SourceKitLSPLegend.swift index 21dc91c0c..50d6593d4 100644 --- a/Sources/SourceKitLSP/SemanticTokensLegend+SourceKitLSPLegend.swift +++ b/Sources/SourceKitLSP/SemanticTokensLegend+SourceKitLSPLegend.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol extension SemanticTokenTypes { // LSP doesn’t know about actors. Display actors as classes. diff --git a/Sources/SourceKitLSP/SharedWorkDoneProgressManager.swift b/Sources/SourceKitLSP/SharedWorkDoneProgressManager.swift index 7982badae..f5f364d2b 100644 --- a/Sources/SourceKitLSP/SharedWorkDoneProgressManager.swift +++ b/Sources/SourceKitLSP/SharedWorkDoneProgressManager.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions import SwiftExtensions diff --git a/Sources/SourceKitLSP/SourceKitIndexDelegate.swift b/Sources/SourceKitLSP/SourceKitIndexDelegate.swift index 227d1500a..5d2b85c43 100644 --- a/Sources/SourceKitLSP/SourceKitIndexDelegate.swift +++ b/Sources/SourceKitLSP/SourceKitIndexDelegate.swift @@ -12,9 +12,10 @@ import Dispatch import IndexStoreDB -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// `IndexDelegate` for the SourceKit workspace. actor SourceKitIndexDelegate: IndexDelegate { diff --git a/Sources/SourceKitLSP/SourceKitLSPCommandMetadata.swift b/Sources/SourceKitLSP/SourceKitLSPCommandMetadata.swift index 26fdcc835..2ab2342ae 100644 --- a/Sources/SourceKitLSP/SourceKitLSPCommandMetadata.swift +++ b/Sources/SourceKitLSP/SourceKitLSPCommandMetadata.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging /// Represents metadata that SourceKit-LSP injects at every command returned by code actions. /// The ExecuteCommand is not a TextDocumentRequest, so metadata is injected to allow SourceKit-LSP diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index 82802ee17..e58186f41 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -11,19 +11,20 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Dispatch import Foundation import IndexStoreDB -package import LanguageServerProtocol -package import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) package import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging package import SKOptions import SemanticIndex import SourceKitD -package import SwiftExtensions +import SwiftExtensions package import ToolchainRegistry +@_spi(SourceKitLSP) package import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import protocol TSCBasic.FileSystem diff --git a/Sources/SourceKitLSP/SymbolLocation+DocumentURI.swift b/Sources/SourceKitLSP/SymbolLocation+DocumentURI.swift index 44427a462..146918d2d 100644 --- a/Sources/SourceKitLSP/SymbolLocation+DocumentURI.swift +++ b/Sources/SourceKitLSP/SymbolLocation+DocumentURI.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import IndexStoreDB -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol extension SymbolLocation { package var documentUri: DocumentURI { diff --git a/Sources/SourceKitLSP/SyntacticTestIndex.swift b/Sources/SourceKitLSP/SyntacticTestIndex.swift index 9c2049c5d..366afeabd 100644 --- a/Sources/SourceKitLSP/SyntacticTestIndex.swift +++ b/Sources/SourceKitLSP/SyntacticTestIndex.swift @@ -11,10 +11,11 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// Task metadata for `SyntacticTestIndexer.indexingQueue` private enum TaskMetadata: DependencyTracker, Equatable { diff --git a/Sources/SourceKitLSP/TestDiscovery.swift b/Sources/SourceKitLSP/TestDiscovery.swift index 5aaf939d5..e0a2dd1c2 100644 --- a/Sources/SourceKitLSP/TestDiscovery.swift +++ b/Sources/SourceKitLSP/TestDiscovery.swift @@ -13,10 +13,11 @@ import BuildServerIntegration import Foundation package import IndexStoreDB -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SemanticIndex import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions package enum TestStyle { package static let xcTest = "XCTest" diff --git a/Sources/SourceKitLSP/TextEdit+IsNoop.swift b/Sources/SourceKitLSP/TextEdit+IsNoop.swift index b5ac0ce4e..8e35d303e 100644 --- a/Sources/SourceKitLSP/TextEdit+IsNoop.swift +++ b/Sources/SourceKitLSP/TextEdit+IsNoop.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol extension TextEdit { /// Returns `true` the replaced text is the same as the new text diff --git a/Sources/SourceKitLSP/Workspace.swift b/Sources/SourceKitLSP/Workspace.swift index d1a28cbcd..760a6356d 100644 --- a/Sources/SourceKitLSP/Workspace.swift +++ b/Sources/SourceKitLSP/Workspace.swift @@ -11,17 +11,18 @@ //===----------------------------------------------------------------------===// package import BuildServerIntegration -package import BuildServerProtocol +@_spi(SourceKitLSP) package import BuildServerProtocol import Foundation import IndexStoreDB -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions package import SemanticIndex import SwiftExtensions import TSCExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import struct TSCBasic.RelativePath diff --git a/Sources/SwiftExtensions/AsyncQueue.swift b/Sources/SwiftExtensions/AsyncQueue.swift deleted file mode 100644 index 087013e2d..000000000 --- a/Sources/SwiftExtensions/AsyncQueue.swift +++ /dev/null @@ -1,194 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation - -/// Abstraction layer so we can store a heterogeneous collection of tasks in an -/// array. -private protocol AnyTask: Sendable { - func waitForCompletion() async - - func cancel() -} - -extension Task: AnyTask { - func waitForCompletion() async { - _ = try? await value - } -} - -/// A type that is able to track dependencies between tasks. -package protocol DependencyTracker: Sendable, Hashable { - /// Whether the task described by `self` needs to finish executing before `other` can start executing. - func isDependency(of other: Self) -> Bool -} - -/// A dependency tracker where each task depends on every other, i.e. a serial -/// queue. -package struct Serial: DependencyTracker { - package func isDependency(of other: Serial) -> Bool { - return true - } -} - -package struct PendingTask: Sendable { - /// The task that is pending. - fileprivate let task: any AnyTask - - /// A unique value used to identify the task. This allows tasks to get - /// removed from `pendingTasks` again after they finished executing. - fileprivate let id: UUID -} - -/// A list of pending tasks that can be sent across actor boundaries and is guarded by a lock. -/// -/// - Note: Unchecked sendable because the tasks are being protected by a lock. -private final class PendingTasks: Sendable { - /// Lock guarding `pendingTasks`. - private let lock = NSLock() - - /// Pending tasks that have not finished execution yet. - /// - /// - Important: This must only be accessed while `lock` has been acquired. - private nonisolated(unsafe) var tasksByMetadata: [TaskMetadata: [PendingTask]] = [:] - - init() { - self.lock.name = "AsyncQueue" - } - - /// Capture a lock and execute the closure, which may modify the pending tasks. - func withLock( - _ body: (_ tasksByMetadata: inout [TaskMetadata: [PendingTask]]) throws -> T - ) rethrows -> T { - try lock.withLock { - try body(&tasksByMetadata) - } - } -} - -/// A queue that allows the execution of asynchronous blocks of code. -package final class AsyncQueue: Sendable { - private let pendingTasks: PendingTasks = PendingTasks() - - package init() {} - - /// Schedule a new closure to be executed on the queue. - /// - /// If this is a serial queue, all previously added tasks are guaranteed to - /// finished executing before this closure gets executed. - /// - /// If this is a barrier, all previously scheduled tasks are guaranteed to - /// finish execution before the barrier is executed and all tasks that are - /// added later will wait until the barrier finishes execution. - @discardableResult - package func async( - priority: TaskPriority? = nil, - metadata: TaskMetadata, - @_inheritActorContext operation: @escaping @Sendable () async -> Success - ) -> Task { - let throwingTask = asyncThrowing(priority: priority, metadata: metadata, operation: operation) - return Task(priority: priority) { - do { - return try await throwingTask.valuePropagatingCancellation - } catch { - // We know this can never happen because `operation` does not throw. - preconditionFailure("Executing a task threw an error even though the operation did not throw") - } - } - } - - /// Same as ``AsyncQueue/async(priority:barrier:operation:)`` but allows the - /// operation to throw. - /// - /// - Important: The caller is responsible for handling any errors thrown from - /// the operation by awaiting the result of the returned task. - package func asyncThrowing( - priority: TaskPriority? = nil, - metadata: TaskMetadata, - @_inheritActorContext operation: @escaping @Sendable () async throws -> Success - ) -> Task { - let id = UUID() - - return pendingTasks.withLock { tasksByMetadata in - // Build the list of tasks that need to finished execution before this one - // can be executed - var dependencies: [PendingTask] = [] - for (pendingMetadata, pendingTasks) in tasksByMetadata { - guard pendingMetadata.isDependency(of: metadata) else { - // No dependency - continue - } - if metadata.isDependency(of: metadata), let lastPendingTask = pendingTasks.last { - // This kind of task depends on all other tasks of the same kind finishing. It is sufficient to just wait on - // the last task with this metadata, it will have all the other tasks with the same metadata as transitive - // dependencies. - dependencies.append(lastPendingTask) - } else { - // We depend on tasks with this metadata, but they don't have any dependencies between them, eg. - // `documentUpdate` depends on all `documentRequest` but `documentRequest` don't have dependencies between - // them. We need to depend on all of them unless we knew that we depended on some other task that already - // depends on all of these. But determining that would also require knowledge about the entire dependency - // graph, which is likely as expensive as depending on all of these tasks. - dependencies += pendingTasks - } - } - - // Schedule the task. - let task = Task(priority: priority) { [pendingTasks] in - // IMPORTANT: The only throwing call in here must be the call to - // operation. Otherwise the assumption that the task will never throw - // if `operation` does not throw, which we are making in `async` does - // not hold anymore. - for dependency in dependencies { - await dependency.task.waitForCompletion() - } - - let result = try await operation() - - pendingTasks.withLock { tasksByMetadata in - tasksByMetadata[metadata, default: []].removeAll(where: { $0.id == id }) - if tasksByMetadata[metadata]?.isEmpty ?? false { - tasksByMetadata[metadata] = nil - } - } - - return result - } - - tasksByMetadata[metadata, default: []].append(PendingTask(task: task, id: id)) - - return task - } - } -} - -/// Convenience overloads for serial queues. -extension AsyncQueue where TaskMetadata == Serial { - /// Same as ``async(priority:operation:)`` but specialized for serial queues - /// that don't specify any metadata. - @discardableResult - package func async( - priority: TaskPriority? = nil, - @_inheritActorContext operation: @escaping @Sendable () async -> Success - ) -> Task { - return self.async(priority: priority, metadata: Serial(), operation: operation) - } - - /// Same as ``asyncThrowing(priority:metadata:operation:)`` but specialized - /// for serial queues that don't specify any metadata. - package func asyncThrowing( - priority: TaskPriority? = nil, - @_inheritActorContext operation: @escaping @Sendable () async throws -> Success - ) -> Task { - return self.asyncThrowing(priority: priority, metadata: Serial(), operation: operation) - } -} diff --git a/Sources/SwiftExtensions/AsyncUtils.swift b/Sources/SwiftExtensions/AsyncUtils.swift index de2dc35a2..33acb53cc 100644 --- a/Sources/SwiftExtensions/AsyncUtils.swift +++ b/Sources/SwiftExtensions/AsyncUtils.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information @@ -10,258 +10,7 @@ // //===----------------------------------------------------------------------===// -import Foundation - -/// Wrapper around a task that allows multiple clients to depend on the task's value. -/// -/// If all of the dependents are cancelled, the underlying task is cancelled as well. -package actor RefCountedCancellableTask { - package let task: Task - - /// The number of clients that depend on the task's result and that are not cancelled. - private var refCount: Int = 0 - - /// Whether the task has been cancelled. - package private(set) var isCancelled: Bool = false - - package init(priority: TaskPriority? = nil, operation: @escaping @Sendable @concurrent () async throws -> Success) { - self.task = Task(priority: priority, operation: operation) - } - - private func decrementRefCount() { - refCount -= 1 - if refCount == 0 { - self.cancel() - } - } - - /// Get the task's value. - /// - /// If all callers of `value` are cancelled, the underlying task gets cancelled as well. - package var value: Success { - get async throws { - if isCancelled { - throw CancellationError() - } - refCount += 1 - return try await withTaskCancellationHandler { - return try await task.value - } onCancel: { - Task { - await self.decrementRefCount() - } - } - } - } - - /// Cancel the task and throw a `CancellationError` to all clients that are awaiting the value. - package func cancel() { - isCancelled = true - task.cancel() - } -} - -package extension Task { - /// Awaits the value of the result. - /// - /// If the current task is cancelled, this will cancel the subtask as well. - var valuePropagatingCancellation: Success { - get async throws { - try await withTaskCancellationHandler { - return try await self.value - } onCancel: { - self.cancel() - } - } - } -} - -package extension Task where Failure == Never { - /// Awaits the value of the result. - /// - /// If the current task is cancelled, this will cancel the subtask as well. - var valuePropagatingCancellation: Success { - get async { - await withTaskCancellationHandler { - return await self.value - } onCancel: { - self.cancel() - } - } - } -} - -/// Allows the execution of a cancellable operation that returns the results -/// via a completion handler. -/// -/// `operation` must invoke the continuation's `resume` method exactly once. -/// -/// If the task executing `withCancellableCheckedThrowingContinuation` gets -/// cancelled, `cancel` is invoked with the handle that `operation` provided. -package func withCancellableCheckedThrowingContinuation( - _ operation: (_ continuation: CheckedContinuation) -> Handle, - cancel: @Sendable (Handle) -> Void -) async throws -> Result { - let handleWrapper = ThreadSafeBox(initialValue: nil) - - @Sendable - func callCancel() { - /// Take the request ID out of the box. This ensures that we only send the - /// cancel notification once in case the `Task.isCancelled` and the - /// `onCancel` check race. - if let handle = handleWrapper.takeValue() { - cancel(handle) - } - } - - return try await withTaskCancellationHandler( - operation: { - try Task.checkCancellation() - return try await withCheckedThrowingContinuation { continuation in - handleWrapper.value = operation(continuation) - - // Check if the task was cancelled. This ensures we send a - // CancelNotification even if the task gets cancelled after we register - // the cancellation handler but before we set the `requestID`. - if Task.isCancelled { - callCancel() - } - } - }, - onCancel: callCancel - ) -} - -extension Collection where Self: Sendable, Element: Sendable { - /// Transforms all elements in the collection concurrently and returns the transformed collection. - package func concurrentMap( - maxConcurrentTasks: Int = ProcessInfo.processInfo.activeProcessorCount, - _ transform: @escaping @Sendable (Element) async -> TransformedElement - ) async -> [TransformedElement] { - let indexedResults = await withTaskGroup(of: (index: Int, element: TransformedElement).self) { taskGroup in - var indexedResults: [(index: Int, element: TransformedElement)] = [] - for (index, element) in self.enumerated() { - if index >= maxConcurrentTasks { - // Wait for one item to finish being transformed so we don't exceed the maximum number of concurrent tasks. - if let (index, transformedElement) = await taskGroup.next() { - indexedResults.append((index, transformedElement)) - } - } - taskGroup.addTask { - return (index, await transform(element)) - } - } - - // Wait for all remaining elements to be transformed. - for await (index, transformedElement) in taskGroup { - indexedResults.append((index, transformedElement)) - } - return indexedResults - } - return [TransformedElement](unsafeUninitializedCapacity: indexedResults.count) { buffer, count in - for (index, transformedElement) in indexedResults { - (buffer.baseAddress! + index).initialize(to: transformedElement) - } - count = indexedResults.count - } - } - - /// Invoke `body` for every element in the collection and wait for all calls of `body` to finish - package func concurrentForEach(_ body: @escaping @Sendable (Element) async -> Void) async { - await withTaskGroup(of: Void.self) { taskGroup in - for element in self { - taskGroup.addTask { - await body(element) - } - } - } - } -} - -package struct TimeoutError: Error, CustomStringConvertible { - package var description: String { "Timed out" } - - package let handle: TimeoutHandle? - - package init(handle: TimeoutHandle?) { - self.handle = handle - } -} - -package final class TimeoutHandle: Equatable, Sendable { - package init() {} - - static package func == (_ lhs: TimeoutHandle, _ rhs: TimeoutHandle) -> Bool { - return lhs === rhs - } -} - -/// Executes `body`. If it doesn't finish after `duration`, throws a `TimeoutError` and cancels `body`. -/// -/// `TimeoutError` is thrown immediately an the function does not wait for `body` to honor the cancellation. -/// -/// If a `handle` is passed in and this `withTimeout` call times out, the thrown `TimeoutError` contains this handle. -/// This way a caller can identify whether this call to `withTimeout` timed out or if a nested call timed out. -package func withTimeout( - _ duration: Duration, - handle: TimeoutHandle? = nil, - _ body: @escaping @Sendable () async throws -> T -) async throws -> T { - // Get the priority with which to launch the body task here so that we can pass the same priority as the initial - // priority to `withTaskPriorityChangedHandler`. Otherwise, we can get into a race condition where bodyTask gets - // launched with a low priority, then the priority gets elevated before we call with `withTaskPriorityChangedHandler`, - // we thus don't receive a `taskPriorityChanged` and hence never increase the priority of `bodyTask`. - let priority = Task.currentPriority - var mutableTasks: [Task] = [] - let stream = AsyncThrowingStream { continuation in - let bodyTask = Task(priority: priority) { - do { - let result = try await body() - continuation.yield(result) - } catch { - continuation.yield(with: .failure(error)) - } - } - - let timeoutTask = Task(priority: priority) { - try await Task.sleep(for: duration) - continuation.yield(with: .failure(TimeoutError(handle: handle))) - bodyTask.cancel() - } - mutableTasks = [bodyTask, timeoutTask] - } - - let tasks = mutableTasks - - defer { - // Be extra careful and ensure that we don't leave `bodyTask` or `timeoutTask` running when `withTimeout` finishes, - // eg. if `withTaskPriorityChangedHandler` adds some behavior that never executes `body` if the task gets cancelled. - for task in tasks { - task.cancel() - } - } - - return try await withTaskPriorityChangedHandler(initialPriority: priority) { - for try await value in stream { - return value - } - // The only reason for the loop above to terminate is if the Task got cancelled or if the stream finishes - // (which it never does). - if Task.isCancelled { - // Throwing a `CancellationError` will make us return from `withTimeout`. We will cancel the `bodyTask` from the - // `defer` method above. - throw CancellationError() - } else { - preconditionFailure("Continuation never finishes") - } - } taskPriorityChanged: { - for task in tasks { - Task(priority: Task.currentPriority) { - _ = try? await task.value - } - } - } -} +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions package enum WithTimeoutResult { case result(T) @@ -332,17 +81,3 @@ package func withTimeout( case .result(let result): return result } } - -/// Same as `withTimeout` above but allows `body` to return an optional value. -package func withTimeout( - _ timeout: Duration, - body: @escaping @Sendable () async throws -> T?, - resultReceivedAfterTimeout: @escaping @Sendable (_ result: T?) async -> Void -) async throws -> T? { - let result: T?? = try await withTimeout(timeout, body: body, resultReceivedAfterTimeout: resultReceivedAfterTimeout) - switch result { - case .none: return nil - case .some(.none): return nil - case .some(.some(let value)): return value - } -} diff --git a/Sources/SwiftExtensions/Atomics.swift b/Sources/SwiftExtensions/Atomics.swift deleted file mode 100644 index f930704fa..000000000 --- a/Sources/SwiftExtensions/Atomics.swift +++ /dev/null @@ -1,106 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import CAtomics - -// TODO: Use atomic types from the standard library (https://github.com/swiftlang/sourcekit-lsp/issues/1949) -package final class AtomicBool: Sendable { - private nonisolated(unsafe) let atomic: UnsafeMutablePointer - - package init(initialValue: Bool) { - self.atomic = atomic_uint32_create(initialValue ? 1 : 0) - } - - deinit { - atomic_uint32_destroy(atomic) - } - - package var value: Bool { - get { - atomic_uint32_get(atomic) != 0 - } - set { - atomic_uint32_set(atomic, newValue ? 1 : 0) - } - } -} - -package final class AtomicUInt8: Sendable { - private nonisolated(unsafe) let atomic: UnsafeMutablePointer - - package init(initialValue: UInt8) { - self.atomic = atomic_uint32_create(UInt32(initialValue)) - } - - deinit { - atomic_uint32_destroy(atomic) - } - - package var value: UInt8 { - get { - UInt8(atomic_uint32_get(atomic)) - } - set { - atomic_uint32_set(atomic, UInt32(newValue)) - } - } -} - -package final class AtomicUInt32: Sendable { - private nonisolated(unsafe) let atomic: UnsafeMutablePointer - - package init(initialValue: UInt32) { - self.atomic = atomic_uint32_create(initialValue) - } - - package var value: UInt32 { - get { - atomic_uint32_get(atomic) - } - set { - atomic_uint32_set(atomic, newValue) - } - } - - deinit { - atomic_uint32_destroy(atomic) - } - - package func fetchAndIncrement() -> UInt32 { - return atomic_uint32_fetch_and_increment(atomic) - } -} - -package final class AtomicInt32: Sendable { - private nonisolated(unsafe) let atomic: UnsafeMutablePointer - - package init(initialValue: Int32) { - self.atomic = atomic_int32_create(initialValue) - } - - package var value: Int32 { - get { - atomic_int32_get(atomic) - } - set { - atomic_int32_set(atomic, newValue) - } - } - - deinit { - atomic_int32_destroy(atomic) - } - - package func fetchAndIncrement() -> Int32 { - return atomic_int32_fetch_and_increment(atomic) - } -} diff --git a/Sources/SwiftExtensions/CMakeLists.txt b/Sources/SwiftExtensions/CMakeLists.txt index 788d77e34..88aa60615 100644 --- a/Sources/SwiftExtensions/CMakeLists.txt +++ b/Sources/SwiftExtensions/CMakeLists.txt @@ -1,12 +1,11 @@ set(sources Array+Safe.swift - AsyncQueue.swift AsyncUtils.swift - Atomics.swift Cache.swift CartesianProduct.swift Collection+Only.swift Collection+PartitionIntoBatches.swift + DisableSigpipe.swift Duration+Seconds.swift FileManagerExtensions.swift LazyValue.swift @@ -18,7 +17,6 @@ set(sources RunWithCleanup.swift Sequence+AsyncMap.swift Sequence+ContainsAnyIn.swift - Task+WithPriorityChangedHandler.swift ThreadSafeBox.swift TransitiveClosure.swift URLExtensions.swift @@ -28,14 +26,18 @@ add_library(SwiftExtensions STATIC ${sources}) set_target_properties(SwiftExtensions PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(SwiftExtensions PUBLIC - CAtomics) + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions) target_link_libraries(SwiftExtensions PRIVATE $<$>:Foundation>) +target_compile_options(SourceKitDForPlugin PRIVATE + $<$: + "SHELL:-module-alias ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin" + >) add_library(SwiftExtensionsForPlugin STATIC ${sources}) set_target_properties(SwiftExtensionsForPlugin PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(SwiftExtensionsForPlugin PUBLIC - CAtomics) + SwiftToolsProtocols::_ToolsProtocolsSwiftExtensionsForPlugin) target_link_libraries(SwiftExtensionsForPlugin PRIVATE $<$>:Foundation>) diff --git a/Sources/LanguageServerProtocolJSONRPC/DisableSigpipe.swift b/Sources/SwiftExtensions/DisableSigpipe.swift similarity index 96% rename from Sources/LanguageServerProtocolJSONRPC/DisableSigpipe.swift rename to Sources/SwiftExtensions/DisableSigpipe.swift index 3035104a9..c84bd5fca 100644 --- a/Sources/LanguageServerProtocolJSONRPC/DisableSigpipe.swift +++ b/Sources/SwiftExtensions/DisableSigpipe.swift @@ -2,7 +2,7 @@ // // This source file is part of the Swift.org open source project // -// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors +// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information diff --git a/Sources/SwiftExtensions/PipeAsStringHandler.swift b/Sources/SwiftExtensions/PipeAsStringHandler.swift index 3d12dba7f..fc4492d89 100644 --- a/Sources/SwiftExtensions/PipeAsStringHandler.swift +++ b/Sources/SwiftExtensions/PipeAsStringHandler.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// package import Foundation +import ToolsProtocolsSwiftExtensions /// Gathers data from a stdout or stderr pipe. When it has accumulated a full line, calls the handler to handle the /// string. diff --git a/Sources/SwiftExtensions/Task+WithPriorityChangedHandler.swift b/Sources/SwiftExtensions/Task+WithPriorityChangedHandler.swift deleted file mode 100644 index df654c99d..000000000 --- a/Sources/SwiftExtensions/Task+WithPriorityChangedHandler.swift +++ /dev/null @@ -1,71 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -/// Runs `operation`. If the task's priority changes while the operation is running, calls `taskPriorityChanged`. -/// -/// Since Swift Concurrency doesn't support direct observation of a task's priority, this polls the task's priority at -/// `pollingInterval`. -/// The function assumes that the original priority of the task is `initialPriority`. If the task priority changed -/// compared to `initialPriority`, the `taskPriorityChanged` will be called. -package func withTaskPriorityChangedHandler( - initialPriority: TaskPriority = Task.currentPriority, - pollingInterval: Duration = .seconds(0.1), - @_inheritActorContext operation: @escaping @Sendable () async throws -> T, - taskPriorityChanged: @escaping @Sendable () -> Void -) async throws -> T { - let lastPriority = ThreadSafeBox(initialValue: initialPriority) - let result: T? = try await withThrowingTaskGroup(of: Optional.self) { taskGroup in - defer { - // We leave this closure when either we have received a result or we registered cancellation. In either case, we - // want to make sure that we don't leave the body task or the priority watching task running. - taskGroup.cancelAll() - } - taskGroup.addTask(priority: initialPriority) { - while true { - if Task.isCancelled { - break - } - let newPriority = Task.currentPriority - let didChange = lastPriority.withLock { lastPriority in - if newPriority != lastPriority { - lastPriority = newPriority - return true - } - return false - } - if didChange { - taskPriorityChanged() - } - do { - try await Task.sleep(for: pollingInterval) - } catch { - break - } - } - return nil - } - taskGroup.addTask { - try await operation() - } - // The first task that watches the priority never finishes unless it is cancelled, so we are effectively await the - // `operation` task here. - // We do need to await the observation task as well so that priority escalation also affects the observation task. - for try await case let value? in taskGroup { - return value - } - return nil - } - guard let result else { - throw CancellationError() - } - return result -} diff --git a/Sources/SwiftLanguageService/AdjustPositionToStartOfArgument.swift b/Sources/SwiftLanguageService/AdjustPositionToStartOfArgument.swift index dadc54a2f..b4c846637 100644 --- a/Sources/SwiftLanguageService/AdjustPositionToStartOfArgument.swift +++ b/Sources/SwiftLanguageService/AdjustPositionToStartOfArgument.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/AdjustPositionToStartOfIdentifier.swift b/Sources/SwiftLanguageService/AdjustPositionToStartOfIdentifier.swift index 3ffb08311..99c3c945a 100644 --- a/Sources/SwiftLanguageService/AdjustPositionToStartOfIdentifier.swift +++ b/Sources/SwiftLanguageService/AdjustPositionToStartOfIdentifier.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/CMakeLists.txt b/Sources/SwiftLanguageService/CMakeLists.txt index 495187e48..022405bc7 100644 --- a/Sources/SwiftLanguageService/CMakeLists.txt +++ b/Sources/SwiftLanguageService/CMakeLists.txt @@ -52,7 +52,8 @@ set_target_properties(SwiftLanguageService PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(SwiftLanguageService PUBLIC BuildServerIntegration - LanguageServerProtocol + Crypto + SwiftToolsProtocols::LanguageServerProtocol SKOptions SourceKitD SourceKitLSP @@ -62,17 +63,17 @@ target_link_libraries(SwiftLanguageService PUBLIC SwiftSyntax::SwiftSyntax ) -target_link_libraries(SourceKitLSP PRIVATE - BuildServerProtocol +target_link_libraries(SwiftLanguageService PRIVATE + SwiftToolsProtocols::BuildServerProtocol Csourcekitd LanguageServerProtocolExtensions - LanguageServerProtocolJSONRPC + SwiftToolsProtocols::LanguageServerProtocolTransport SemanticIndex - SKLogging + SwiftToolsProtocols::SKLogging SKUtilities SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions TSCExtensions - Crypto TSCBasic SwiftSyntax::SwiftDiagnostics SwiftSyntax::SwiftIDEUtils diff --git a/Sources/SwiftLanguageService/CodeActions/ConvertIntegerLiteral.swift b/Sources/SwiftLanguageService/CodeActions/ConvertIntegerLiteral.swift index bb84a2d1f..eaf5fdd33 100644 --- a/Sources/SwiftLanguageService/CodeActions/ConvertIntegerLiteral.swift +++ b/Sources/SwiftLanguageService/CodeActions/ConvertIntegerLiteral.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftRefactor import SwiftSyntax diff --git a/Sources/SwiftLanguageService/CodeActions/ConvertJSONToCodableStruct.swift b/Sources/SwiftLanguageService/CodeActions/ConvertJSONToCodableStruct.swift index fd29e35e7..f97f5783b 100644 --- a/Sources/SwiftLanguageService/CodeActions/ConvertJSONToCodableStruct.swift +++ b/Sources/SwiftLanguageService/CodeActions/ConvertJSONToCodableStruct.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SwiftBasicFormat import SwiftParser import SwiftRefactor diff --git a/Sources/SwiftLanguageService/CodeActions/ConvertStringConcatenationToStringInterpolation.swift b/Sources/SwiftLanguageService/CodeActions/ConvertStringConcatenationToStringInterpolation.swift index 02741581a..359faab9d 100644 --- a/Sources/SwiftLanguageService/CodeActions/ConvertStringConcatenationToStringInterpolation.swift +++ b/Sources/SwiftLanguageService/CodeActions/ConvertStringConcatenationToStringInterpolation.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SwiftRefactor import SwiftSyntax diff --git a/Sources/SwiftLanguageService/CodeActions/PackageManifestEdits.swift b/Sources/SwiftLanguageService/CodeActions/PackageManifestEdits.swift index 8ea598fcf..c9939f354 100644 --- a/Sources/SwiftLanguageService/CodeActions/PackageManifestEdits.swift +++ b/Sources/SwiftLanguageService/CodeActions/PackageManifestEdits.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftParser @_spi(PackageRefactor) import SwiftRefactor diff --git a/Sources/SwiftLanguageService/CodeActions/RemoveUnusedImports.swift b/Sources/SwiftLanguageService/CodeActions/RemoveUnusedImports.swift index a6601d227..ec39eea75 100644 --- a/Sources/SwiftLanguageService/CodeActions/RemoveUnusedImports.swift +++ b/Sources/SwiftLanguageService/CodeActions/RemoveUnusedImports.swift @@ -14,7 +14,7 @@ import BuildServerIntegration import Csourcekitd import Foundation package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP import SwiftExtensions diff --git a/Sources/SwiftLanguageService/CodeActions/SyntaxCodeActionProvider.swift b/Sources/SwiftLanguageService/CodeActions/SyntaxCodeActionProvider.swift index 35c3c8884..4379a503c 100644 --- a/Sources/SwiftLanguageService/CodeActions/SyntaxCodeActionProvider.swift +++ b/Sources/SwiftLanguageService/CodeActions/SyntaxCodeActionProvider.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitLSP import SwiftRefactor import SwiftSyntax diff --git a/Sources/SwiftLanguageService/CodeActions/SyntaxRefactoringCodeActionProvider.swift b/Sources/SwiftLanguageService/CodeActions/SyntaxRefactoringCodeActionProvider.swift index 08ce89437..79831ad81 100644 --- a/Sources/SwiftLanguageService/CodeActions/SyntaxRefactoringCodeActionProvider.swift +++ b/Sources/SwiftLanguageService/CodeActions/SyntaxRefactoringCodeActionProvider.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftRefactor import SwiftSyntax diff --git a/Sources/SwiftLanguageService/CodeCompletion.swift b/Sources/SwiftLanguageService/CodeCompletion.swift index 69f1e1e52..fa4dbad97 100644 --- a/Sources/SwiftLanguageService/CodeCompletion.swift +++ b/Sources/SwiftLanguageService/CodeCompletion.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP import SwiftBasicFormat diff --git a/Sources/SwiftLanguageService/CodeCompletionSession.swift b/Sources/SwiftLanguageService/CodeCompletionSession.swift index 430a6ae09..2a6af04f0 100644 --- a/Sources/SwiftLanguageService/CodeCompletionSession.swift +++ b/Sources/SwiftLanguageService/CodeCompletionSession.swift @@ -13,8 +13,8 @@ import Csourcekitd import Dispatch import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKUtilities import SourceKitD @@ -24,6 +24,7 @@ import SwiftExtensions import SwiftParser @_spi(SourceKitLSP) import SwiftRefactor import SwiftSyntax +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions /// Uniquely identifies a code completion session. We need this so that when resolving a code completion item, we can /// verify that the item to resolve belongs to the code completion session that is currently open. diff --git a/Sources/SwiftLanguageService/CommentXML.swift b/Sources/SwiftLanguageService/CommentXML.swift index 31b4f44e4..0b221b0d6 100644 --- a/Sources/SwiftLanguageService/CommentXML.swift +++ b/Sources/SwiftLanguageService/CommentXML.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions #if canImport(FoundationXML) import FoundationXML diff --git a/Sources/SwiftLanguageService/CursorInfo.swift b/Sources/SwiftLanguageService/CursorInfo.swift index 3e643d62f..2e19c2755 100644 --- a/Sources/SwiftLanguageService/CursorInfo.swift +++ b/Sources/SwiftLanguageService/CursorInfo.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Csourcekitd -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/Diagnostic.swift b/Sources/SwiftLanguageService/Diagnostic.swift index 6a844432b..e69028b5b 100644 --- a/Sources/SwiftLanguageService/Diagnostic.swift +++ b/Sources/SwiftLanguageService/Diagnostic.swift @@ -12,9 +12,9 @@ import Csourcekitd import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP import SwiftDiagnostics diff --git a/Sources/SwiftLanguageService/DiagnosticReportManager.swift b/Sources/SwiftLanguageService/DiagnosticReportManager.swift index 3c44179b1..05cca8e6a 100644 --- a/Sources/SwiftLanguageService/DiagnosticReportManager.swift +++ b/Sources/SwiftLanguageService/DiagnosticReportManager.swift @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKUtilities import SourceKitD @@ -20,6 +20,7 @@ import SourceKitLSP import SwiftDiagnostics import SwiftExtensions import SwiftParserDiagnostics +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct SourceKitLSP.Diagnostic diff --git a/Sources/SwiftLanguageService/DocumentFormatting.swift b/Sources/SwiftLanguageService/DocumentFormatting.swift index 635dd8935..4ede6c313 100644 --- a/Sources/SwiftLanguageService/DocumentFormatting.swift +++ b/Sources/SwiftLanguageService/DocumentFormatting.swift @@ -11,16 +11,17 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitLSP import SwiftExtensions import SwiftParser import SwiftSyntax import TSCExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import struct TSCBasic.AbsolutePath import class TSCBasic.LocalFileOutputByteStream diff --git a/Sources/SwiftLanguageService/DocumentSymbols.swift b/Sources/SwiftLanguageService/DocumentSymbols.swift index 0a732a041..7d991d82e 100644 --- a/Sources/SwiftLanguageService/DocumentSymbols.swift +++ b/Sources/SwiftLanguageService/DocumentSymbols.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/ExpandMacroCommand.swift b/Sources/SwiftLanguageService/ExpandMacroCommand.swift index 3fac467b3..93c8ba3cf 100644 --- a/Sources/SwiftLanguageService/ExpandMacroCommand.swift +++ b/Sources/SwiftLanguageService/ExpandMacroCommand.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SourceKitD package struct ExpandMacroCommand: SwiftCommand { diff --git a/Sources/SwiftLanguageService/FoldingRange.swift b/Sources/SwiftLanguageService/FoldingRange.swift index 0b04f8836..6c0890447 100644 --- a/Sources/SwiftLanguageService/FoldingRange.swift +++ b/Sources/SwiftLanguageService/FoldingRange.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/GeneratedInterfaceManager.swift b/Sources/SwiftLanguageService/GeneratedInterfaceManager.swift index bedb73b67..ac23955f4 100644 --- a/Sources/SwiftLanguageService/GeneratedInterfaceManager.swift +++ b/Sources/SwiftLanguageService/GeneratedInterfaceManager.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/InlayHints.swift b/Sources/SwiftLanguageService/InlayHints.swift index 12f1d0147..1133d222d 100644 --- a/Sources/SwiftLanguageService/InlayHints.swift +++ b/Sources/SwiftLanguageService/InlayHints.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SourceKitLSP import SwiftExtensions import SwiftSyntax diff --git a/Sources/SwiftLanguageService/MacroExpansion.swift b/Sources/SwiftLanguageService/MacroExpansion.swift index 38494d379..679d3e70c 100644 --- a/Sources/SwiftLanguageService/MacroExpansion.swift +++ b/Sources/SwiftLanguageService/MacroExpansion.swift @@ -10,11 +10,11 @@ // //===----------------------------------------------------------------------===// -import Crypto +private import Crypto import Csourcekitd import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKUtilities import SourceKitD diff --git a/Sources/SwiftLanguageService/OpenInterface.swift b/Sources/SwiftLanguageService/OpenInterface.swift index d6f9d402a..52a77e9ed 100644 --- a/Sources/SwiftLanguageService/OpenInterface.swift +++ b/Sources/SwiftLanguageService/OpenInterface.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging package import SourceKitLSP extension SwiftLanguageService { diff --git a/Sources/SwiftLanguageService/RefactoringEdit.swift b/Sources/SwiftLanguageService/RefactoringEdit.swift index 341cbb2b8..3dc70635b 100644 --- a/Sources/SwiftLanguageService/RefactoringEdit.swift +++ b/Sources/SwiftLanguageService/RefactoringEdit.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SourceKitD /// Represents an edit from semantic refactor response. Notionally, a subclass of `TextEdit` diff --git a/Sources/SwiftLanguageService/RefactoringResponse.swift b/Sources/SwiftLanguageService/RefactoringResponse.swift index 45b1a5672..34befa838 100644 --- a/Sources/SwiftLanguageService/RefactoringResponse.swift +++ b/Sources/SwiftLanguageService/RefactoringResponse.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Csourcekitd -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/RelatedIdentifiers.swift b/Sources/SwiftLanguageService/RelatedIdentifiers.swift index 3764487f3..cdb21620f 100644 --- a/Sources/SwiftLanguageService/RelatedIdentifiers.swift +++ b/Sources/SwiftLanguageService/RelatedIdentifiers.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Csourcekitd -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/Rename.swift b/Sources/SwiftLanguageService/Rename.swift index 26195782f..43ba8211f 100644 --- a/Sources/SwiftLanguageService/Rename.swift +++ b/Sources/SwiftLanguageService/Rename.swift @@ -13,8 +13,8 @@ import Csourcekitd import Foundation package import IndexStoreDB -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitD package import SourceKitLSP diff --git a/Sources/SwiftLanguageService/RewriteSourceKitPlaceholders.swift b/Sources/SwiftLanguageService/RewriteSourceKitPlaceholders.swift index 4c7444dfc..bf380f995 100644 --- a/Sources/SwiftLanguageService/RewriteSourceKitPlaceholders.swift +++ b/Sources/SwiftLanguageService/RewriteSourceKitPlaceholders.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging @_spi(RawSyntax) import SwiftSyntax /// Translate SourceKit placeholder syntax — `<#foo#>` — in `input` to LSP diff --git a/Sources/SwiftLanguageService/SemanticRefactorCommand.swift b/Sources/SwiftLanguageService/SemanticRefactorCommand.swift index 476f2039f..97671413c 100644 --- a/Sources/SwiftLanguageService/SemanticRefactorCommand.swift +++ b/Sources/SwiftLanguageService/SemanticRefactorCommand.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Csourcekitd -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SourceKitD package struct SemanticRefactorCommand: SwiftCommand { diff --git a/Sources/SwiftLanguageService/SemanticRefactoring.swift b/Sources/SwiftLanguageService/SemanticRefactoring.swift index 0b321faa1..b78972600 100644 --- a/Sources/SwiftLanguageService/SemanticRefactoring.swift +++ b/Sources/SwiftLanguageService/SemanticRefactoring.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/SemanticTokens.swift b/Sources/SwiftLanguageService/SemanticTokens.swift index 010d299eb..b9fe22a2d 100644 --- a/Sources/SwiftLanguageService/SemanticTokens.swift +++ b/Sources/SwiftLanguageService/SemanticTokens.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP import SwiftIDEUtils diff --git a/Sources/SwiftLanguageService/SignatureHelp.swift b/Sources/SwiftLanguageService/SignatureHelp.swift index 1c74da66f..7d91a8451 100644 --- a/Sources/SwiftLanguageService/SignatureHelp.swift +++ b/Sources/SwiftLanguageService/SignatureHelp.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP import SwiftBasicFormat diff --git a/Sources/SwiftLanguageService/SwiftCodeLensScanner.swift b/Sources/SwiftLanguageService/SwiftCodeLensScanner.swift index 8c2647815..d0a29c92b 100644 --- a/Sources/SwiftLanguageService/SwiftCodeLensScanner.swift +++ b/Sources/SwiftLanguageService/SwiftCodeLensScanner.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/SwiftCommand.swift b/Sources/SwiftLanguageService/SwiftCommand.swift index 54677077f..c6a51197a 100644 --- a/Sources/SwiftLanguageService/SwiftCommand.swift +++ b/Sources/SwiftLanguageService/SwiftCommand.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol /// A `Command` that should be executed by Swift's language server. package protocol SwiftCommand: Codable, Hashable, LSPAnyCodable { diff --git a/Sources/SwiftLanguageService/SwiftLanguageService.swift b/Sources/SwiftLanguageService/SwiftLanguageService.swift index 7cf7593d8..d76c4c697 100644 --- a/Sources/SwiftLanguageService/SwiftLanguageService.swift +++ b/Sources/SwiftLanguageService/SwiftLanguageService.swift @@ -11,14 +11,15 @@ //===----------------------------------------------------------------------===// package import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Csourcekitd import Dispatch import Foundation import IndexStoreDB -package import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging package import SKOptions import SKUtilities import SemanticIndex @@ -29,6 +30,7 @@ import SwiftParser import SwiftParserDiagnostics package import SwiftSyntax package import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions #if os(Windows) import WinSDK diff --git a/Sources/SwiftLanguageService/SwiftTestingScanner.swift b/Sources/SwiftLanguageService/SwiftTestingScanner.swift index 67bac6124..93717cfb5 100644 --- a/Sources/SwiftLanguageService/SwiftTestingScanner.swift +++ b/Sources/SwiftLanguageService/SwiftTestingScanner.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitLSP import SwiftParser import SwiftSyntax diff --git a/Sources/SwiftLanguageService/SymbolGraph.swift b/Sources/SwiftLanguageService/SymbolGraph.swift index 7becaed9a..bdd1514c1 100644 --- a/Sources/SwiftLanguageService/SymbolGraph.swift +++ b/Sources/SwiftLanguageService/SymbolGraph.swift @@ -13,7 +13,7 @@ import BuildServerIntegration import Foundation package import IndexStoreDB -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol package import SourceKitLSP import SwiftExtensions import SwiftSyntax diff --git a/Sources/SwiftLanguageService/SymbolInfo.swift b/Sources/SwiftLanguageService/SymbolInfo.swift index a6e0fed08..29179a22e 100644 --- a/Sources/SwiftLanguageService/SymbolInfo.swift +++ b/Sources/SwiftLanguageService/SymbolInfo.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol +@_spi(SourceKitLSP) package import LanguageServerProtocol import SourceKitLSP extension SwiftLanguageService { diff --git a/Sources/SwiftLanguageService/SyntacticSwiftXCTestScanner.swift b/Sources/SwiftLanguageService/SyntacticSwiftXCTestScanner.swift index eaeb1dae4..f01121290 100644 --- a/Sources/SwiftLanguageService/SyntacticSwiftXCTestScanner.swift +++ b/Sources/SwiftLanguageService/SyntacticSwiftXCTestScanner.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftLanguageService/SyntaxHighlightingToken.swift b/Sources/SwiftLanguageService/SyntaxHighlightingToken.swift index 33ecf36c3..5bc67f064 100644 --- a/Sources/SwiftLanguageService/SyntaxHighlightingToken.swift +++ b/Sources/SwiftLanguageService/SyntaxHighlightingToken.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD /// A ranged token in the document used for syntax highlighting. diff --git a/Sources/SwiftLanguageService/SyntaxHighlightingTokenParser.swift b/Sources/SwiftLanguageService/SyntaxHighlightingTokenParser.swift index 7756fb778..b221cb7fd 100644 --- a/Sources/SwiftLanguageService/SyntaxHighlightingTokenParser.swift +++ b/Sources/SwiftLanguageService/SyntaxHighlightingTokenParser.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Csourcekitd -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD package import SourceKitLSP diff --git a/Sources/SwiftLanguageService/SyntaxHighlightingTokens.swift b/Sources/SwiftLanguageService/SyntaxHighlightingTokens.swift index a7dc1816a..8fa437ad6 100644 --- a/Sources/SwiftLanguageService/SyntaxHighlightingTokens.swift +++ b/Sources/SwiftLanguageService/SyntaxHighlightingTokens.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SourceKitLSP diff --git a/Sources/SwiftLanguageService/SyntaxTreeManager.swift b/Sources/SwiftLanguageService/SyntaxTreeManager.swift index 9a4e9af40..2eb3dba46 100644 --- a/Sources/SwiftLanguageService/SyntaxTreeManager.swift +++ b/Sources/SwiftLanguageService/SyntaxTreeManager.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SKUtilities import SourceKitLSP import SwiftParser diff --git a/Sources/SwiftLanguageService/TestDiscovery.swift b/Sources/SwiftLanguageService/TestDiscovery.swift index 6e11a0853..f77550a82 100644 --- a/Sources/SwiftLanguageService/TestDiscovery.swift +++ b/Sources/SwiftLanguageService/TestDiscovery.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -package import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) package import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SemanticIndex package import SourceKitLSP import SwiftExtensions diff --git a/Sources/SwiftLanguageService/VariableTypeInfo.swift b/Sources/SwiftLanguageService/VariableTypeInfo.swift index 5badbac8f..0cf1b5b40 100644 --- a/Sources/SwiftLanguageService/VariableTypeInfo.swift +++ b/Sources/SwiftLanguageService/VariableTypeInfo.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Dispatch -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SourceKitD import SourceKitLSP import SwiftSyntax diff --git a/Sources/SwiftSourceKitClientPlugin/CMakeLists.txt b/Sources/SwiftSourceKitClientPlugin/CMakeLists.txt index 9a2b1f5a5..9cc6c77d5 100644 --- a/Sources/SwiftSourceKitClientPlugin/CMakeLists.txt +++ b/Sources/SwiftSourceKitClientPlugin/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(SwiftSourceKitClientPlugin PRIVATE Csourcekitd SourceKitD SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions SwiftSourceKitPluginCommon $<$>:FoundationXML>) diff --git a/Sources/SwiftSourceKitPlugin/ASTCompletion/ASTCompletionItem.swift b/Sources/SwiftSourceKitPlugin/ASTCompletion/ASTCompletionItem.swift index 454c25fbe..eb1d524a8 100644 --- a/Sources/SwiftSourceKitPlugin/ASTCompletion/ASTCompletionItem.swift +++ b/Sources/SwiftSourceKitPlugin/ASTCompletion/ASTCompletionItem.swift @@ -13,7 +13,7 @@ import CompletionScoring import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SwiftExtensions diff --git a/Sources/SwiftSourceKitPlugin/ASTCompletion/CompletionSession.swift b/Sources/SwiftSourceKitPlugin/ASTCompletion/CompletionSession.swift index e8620731b..0f803e34b 100644 --- a/Sources/SwiftSourceKitPlugin/ASTCompletion/CompletionSession.swift +++ b/Sources/SwiftSourceKitPlugin/ASTCompletion/CompletionSession.swift @@ -13,7 +13,7 @@ import CompletionScoring import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD /// Represents a code completion session. diff --git a/Sources/SwiftSourceKitPlugin/CMakeLists.txt b/Sources/SwiftSourceKitPlugin/CMakeLists.txt index 342c11bd2..4d45a1360 100644 --- a/Sources/SwiftSourceKitPlugin/CMakeLists.txt +++ b/Sources/SwiftSourceKitPlugin/CMakeLists.txt @@ -35,17 +35,19 @@ target_compile_options(SwiftSourceKitPlugin PRIVATE "SHELL:-module-alias CompletionScoring=CompletionScoringForPlugin" "SHELL:-module-alias SKUtilities=SKUtilitiesForPlugin" "SHELL:-module-alias SourceKitD=SourceKitDForPlugin" - "SHELL:-module-alias SKLogging=SKLoggingForPlugin" + "SHELL:-module-alias SKLogging=_SKLoggingForPlugin" "SHELL:-module-alias SwiftExtensions=SwiftExtensionsForPlugin" + "SHELL:-module-alias ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin" >) target_link_libraries(SwiftSourceKitPlugin PRIVATE Csourcekitd CompletionScoringForPlugin SKUtilitiesForPlugin - SKLoggingForPlugin + SwiftToolsProtocols::_SKLoggingForPlugin SourceKitDForPlugin SwiftSourceKitPluginCommon SwiftExtensionsForPlugin + SwiftToolsProtocols::_ToolsProtocolsSwiftExtensionsForPlugin $<$>:FoundationXML>) install(TARGETS SwiftSourceKitPlugin DESTINATION lib) diff --git a/Sources/SwiftSourceKitPlugin/CodeCompletion/Connection.swift b/Sources/SwiftSourceKitPlugin/CodeCompletion/Connection.swift index 6d4d3eb61..89a002ff2 100644 --- a/Sources/SwiftSourceKitPlugin/CodeCompletion/Connection.swift +++ b/Sources/SwiftSourceKitPlugin/CodeCompletion/Connection.swift @@ -13,7 +13,7 @@ import CompletionScoring import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKUtilities import SourceKitD import SwiftExtensions diff --git a/Sources/SwiftSourceKitPlugin/CompletionProvider.swift b/Sources/SwiftSourceKitPlugin/CompletionProvider.swift index 634976d92..19399c0ba 100644 --- a/Sources/SwiftSourceKitPlugin/CompletionProvider.swift +++ b/Sources/SwiftSourceKitPlugin/CompletionProvider.swift @@ -13,7 +13,7 @@ import CompletionScoring import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SwiftSourceKitPluginCommon diff --git a/Sources/SwiftSourceKitPlugin/Plugin.swift b/Sources/SwiftSourceKitPlugin/Plugin.swift index 2cb97db3a..c03a1d954 100644 --- a/Sources/SwiftSourceKitPlugin/Plugin.swift +++ b/Sources/SwiftSourceKitPlugin/Plugin.swift @@ -12,10 +12,11 @@ public import Csourcekitd import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SourceKitD import SwiftExtensions import SwiftSourceKitPluginCommon +import ToolsProtocolsSwiftExtensions private func useNewAPI(for dict: SKDRequestDictionaryReader) -> Bool { guard let opts: SKDRequestDictionaryReader = dict[dict.sourcekitd.keys.codeCompleteOptions], @@ -209,6 +210,7 @@ public func sourcekitd_plugin_initialize_2( _ params: sourcekitd_api_plugin_initialize_params_t, _ parentLibraryPath: UnsafePointer ) { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp.plugin") let parentLibraryPath = String(cString: parentLibraryPath) #if canImport(Darwin) if parentLibraryPath == "SOURCEKIT_LSP_PLUGIN_PARENT_LIBRARY_RTLD_DEFAULT" { diff --git a/Sources/SwiftSourceKitPluginCommon/CMakeLists.txt b/Sources/SwiftSourceKitPluginCommon/CMakeLists.txt index 747ef4a2a..200350a5a 100644 --- a/Sources/SwiftSourceKitPluginCommon/CMakeLists.txt +++ b/Sources/SwiftSourceKitPluginCommon/CMakeLists.txt @@ -5,14 +5,16 @@ add_library(SwiftSourceKitPluginCommon STATIC target_compile_options(SwiftSourceKitPluginCommon PRIVATE $<$: "SHELL:-module-alias SourceKitD=SourceKitDForPlugin" - "SHELL:-module-alias SKLogging=SKLoggingForPlugin" + "SHELL:-module-alias SKLogging=_SKLoggingForPlugin" "SHELL:-module-alias SwiftExtensions=SwiftExtensionsForPlugin" + "SHELL:-module-alias ToolsProtocolsSwiftExtensions=_ToolsProtocolsSwiftExtensionsForPlugin" >) set_target_properties(SwiftSourceKitPluginCommon PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(SwiftSourceKitPluginCommon PRIVATE Csourcekitd SourceKitDForPlugin - SKLoggingForPlugin + SwiftToolsProtocols::_SKLoggingForPlugin SwiftExtensionsForPlugin - $<$>:FoundationXML>) \ No newline at end of file + SwiftToolsProtocols::_ToolsProtocolsSwiftExtensionsForPlugin + $<$>:FoundationXML>) diff --git a/Sources/SwiftSourceKitPluginCommon/DynamicallyLoadedSourceKitdD+forPlugin.swift b/Sources/SwiftSourceKitPluginCommon/DynamicallyLoadedSourceKitdD+forPlugin.swift index 5caa54944..c55884c2a 100644 --- a/Sources/SwiftSourceKitPluginCommon/DynamicallyLoadedSourceKitdD+forPlugin.swift +++ b/Sources/SwiftSourceKitPluginCommon/DynamicallyLoadedSourceKitdD+forPlugin.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging package import SourceKitD import SwiftExtensions diff --git a/Sources/TSCExtensions/CMakeLists.txt b/Sources/TSCExtensions/CMakeLists.txt index e4b507970..bc462b12f 100644 --- a/Sources/TSCExtensions/CMakeLists.txt +++ b/Sources/TSCExtensions/CMakeLists.txt @@ -9,7 +9,8 @@ add_library(TSCExtensions STATIC set_target_properties(TSCExtensions PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(TSCExtensions PRIVATE - SKLogging + SwiftToolsProtocols::SKLogging SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions TSCBasic $<$>:Foundation>) diff --git a/Sources/TSCExtensions/Process+Run.swift b/Sources/TSCExtensions/Process+Run.swift index 76c9bc91c..34993ffb7 100644 --- a/Sources/TSCExtensions/Process+Run.swift +++ b/Sources/TSCExtensions/Process+Run.swift @@ -11,8 +11,9 @@ //===----------------------------------------------------------------------===// import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions package import struct TSCBasic.AbsolutePath package import class TSCBasic.Process diff --git a/Sources/ToolchainRegistry/CMakeLists.txt b/Sources/ToolchainRegistry/CMakeLists.txt index d1ab6c805..e8276e53f 100644 --- a/Sources/ToolchainRegistry/CMakeLists.txt +++ b/Sources/ToolchainRegistry/CMakeLists.txt @@ -7,8 +7,9 @@ set_target_properties(ToolchainRegistry PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) target_link_libraries(ToolchainRegistry PUBLIC LanguageServerProtocolExtensions - SKLogging + SwiftToolsProtocols::SKLogging SwiftExtensions + SwiftToolsProtocols::ToolsProtocolsSwiftExtensions TSCBasic) target_link_libraries(ToolchainRegistry PRIVATE diff --git a/Sources/ToolchainRegistry/Toolchain.swift b/Sources/ToolchainRegistry/Toolchain.swift index fec13ca8e..d10bcc13a 100644 --- a/Sources/ToolchainRegistry/Toolchain.swift +++ b/Sources/ToolchainRegistry/Toolchain.swift @@ -12,7 +12,7 @@ package import Foundation import RegexBuilder -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions import TSCExtensions diff --git a/Sources/ToolchainRegistry/ToolchainRegistry.swift b/Sources/ToolchainRegistry/ToolchainRegistry.swift index cfa09b155..4e9b45473 100644 --- a/Sources/ToolchainRegistry/ToolchainRegistry.swift +++ b/Sources/ToolchainRegistry/ToolchainRegistry.swift @@ -12,7 +12,7 @@ import Dispatch package import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SwiftExtensions import TSCExtensions diff --git a/Sources/sourcekit-lsp/CMakeLists.txt b/Sources/sourcekit-lsp/CMakeLists.txt index b5d4baf59..0a9c7550e 100644 --- a/Sources/sourcekit-lsp/CMakeLists.txt +++ b/Sources/sourcekit-lsp/CMakeLists.txt @@ -5,9 +5,9 @@ target_link_libraries(sourcekit-lsp PRIVATE BuildServerIntegration Diagnose InProcessClient - LanguageServerProtocol + SwiftToolsProtocols::LanguageServerProtocol LanguageServerProtocolExtensions - LanguageServerProtocolJSONRPC + SwiftToolsProtocols::LanguageServerProtocolTransport SemanticIndex SKOptions SourceKitLSP diff --git a/Sources/sourcekit-lsp/SourceKitLSP.swift b/Sources/sourcekit-lsp/SourceKitLSP.swift index ca8aa9648..502a45978 100644 --- a/Sources/sourcekit-lsp/SourceKitLSP.swift +++ b/Sources/sourcekit-lsp/SourceKitLSP.swift @@ -17,10 +17,10 @@ import Diagnose import Dispatch import Foundation import InProcessClient -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKOptions import SourceKitLSP import SwiftExtensions @@ -235,18 +235,20 @@ struct SourceKitLSP: AsyncParsableCommand { fatalError("failed to redirect stdout -> stderr: \(strerror(errno)!)") } + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp") + logger.log("sourcekit-lsp launched from \(ProcessInfo.processInfo.arguments.first ?? "")") let globalConfigurationOptions = globalConfigurationOptions if let logLevelStr = globalConfigurationOptions.loggingOrDefault.level, let logLevel = NonDarwinLogLevel(logLevelStr) { - LogConfig.logLevel.value = logLevel + LogConfig.logLevel = logLevel } if let privacyLevelStr = globalConfigurationOptions.loggingOrDefault.privacyLevel, let privacyLevel = NonDarwinLogPrivacy(privacyLevelStr) { - LogConfig.privacyLevel.value = privacyLevel + LogConfig.privacyLevel = privacyLevel } let realStdoutHandle = FileHandle(fileDescriptor: realStdout, closeOnDealloc: false) diff --git a/Tests/BuildServerIntegrationTests/BuildServerManagerTests.swift b/Tests/BuildServerIntegrationTests/BuildServerManagerTests.swift index 5f76b1d0e..5b3ad8ece 100644 --- a/Tests/BuildServerIntegrationTests/BuildServerManagerTests.swift +++ b/Tests/BuildServerIntegrationTests/BuildServerManagerTests.swift @@ -11,10 +11,11 @@ //===----------------------------------------------------------------------===// @_spi(Testing) import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SwiftExtensions @@ -82,6 +83,10 @@ private func createBuildServerManager( } final class BuildServerManagerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testMainFiles() async throws { let a = try DocumentURI(string: "bsm:a") let b = try DocumentURI(string: "bsm:b") diff --git a/Tests/BuildServerIntegrationTests/CompilationDatabasePerfTests.swift b/Tests/BuildServerIntegrationTests/CompilationDatabasePerfTests.swift index 969b4e225..b6209870a 100644 --- a/Tests/BuildServerIntegrationTests/CompilationDatabasePerfTests.swift +++ b/Tests/BuildServerIntegrationTests/CompilationDatabasePerfTests.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SKTestSupport import TSCBasic import XCTest diff --git a/Tests/BuildServerIntegrationTests/CompilationDatabaseTests.swift b/Tests/BuildServerIntegrationTests/CompilationDatabaseTests.swift index 4aa86a77b..79a96d19d 100644 --- a/Tests/BuildServerIntegrationTests/CompilationDatabaseTests.swift +++ b/Tests/BuildServerIntegrationTests/CompilationDatabaseTests.swift @@ -11,9 +11,11 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +import SKLogging import SKTestSupport import SwiftExtensions import TSCExtensions @@ -23,6 +25,10 @@ import XCTest import struct TSCBasic.RelativePath final class CompilationDatabaseTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testEncodeCompDBCommand() throws { // Requires JSONEncoder.OutputFormatting.sortedKeys func check( diff --git a/Tests/BuildServerIntegrationTests/ExternalBuildServerTests.swift b/Tests/BuildServerIntegrationTests/ExternalBuildServerTests.swift index d566b243a..16c65ccbf 100644 --- a/Tests/BuildServerIntegrationTests/ExternalBuildServerTests.swift +++ b/Tests/BuildServerIntegrationTests/ExternalBuildServerTests.swift @@ -11,10 +11,11 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +import SKLogging import SKOptions import SKTestSupport import SourceKitLSP @@ -27,6 +28,10 @@ import WinSDK #endif final class ExternalBuildServerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testBuildSettingsFromBuildServer() async throws { let project = try await ExternalBuildServerTestProject( files: [ diff --git a/Tests/BuildServerIntegrationTests/FallbackBuildServerTests.swift b/Tests/BuildServerIntegrationTests/FallbackBuildServerTests.swift index d5efe8cce..435131898 100644 --- a/Tests/BuildServerIntegrationTests/FallbackBuildServerTests.swift +++ b/Tests/BuildServerIntegrationTests/FallbackBuildServerTests.swift @@ -11,8 +11,9 @@ //===----------------------------------------------------------------------===// @_spi(Testing) import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKOptions import SKTestSupport import SourceKitLSP @@ -20,6 +21,9 @@ import TSCBasic import XCTest final class FallbackBuildServerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } func testSwift() throws { let sdk = try AbsolutePath(validating: "/my/sdk").pathString diff --git a/Tests/BuildServerIntegrationTests/LegacyBuildServerBuildSystemTests.swift b/Tests/BuildServerIntegrationTests/LegacyBuildServerBuildSystemTests.swift index ce2589199..c2c335ff1 100644 --- a/Tests/BuildServerIntegrationTests/LegacyBuildServerBuildSystemTests.swift +++ b/Tests/BuildServerIntegrationTests/LegacyBuildServerBuildSystemTests.swift @@ -11,15 +11,20 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +import SKLogging import SKTestSupport import TSCBasic import XCTest final class LegacyBuildServerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testBuildSettingsFromBuildServer() async throws { let project = try await ExternalBuildServerTestProject( files: [ diff --git a/Tests/BuildServerIntegrationTests/SwiftPMBuildServerTests.swift b/Tests/BuildServerIntegrationTests/SwiftPMBuildServerTests.swift index 4eab2e0d6..cd1af0b24 100644 --- a/Tests/BuildServerIntegrationTests/SwiftPMBuildServerTests.swift +++ b/Tests/BuildServerIntegrationTests/SwiftPMBuildServerTests.swift @@ -11,11 +11,13 @@ //===----------------------------------------------------------------------===// #if !NO_SWIFTPM_DEPENDENCY -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol @_spi(Testing) import BuildServerIntegration -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport import PackageModel +import SKLogging import SKOptions import SKTestSupport import SourceKitLSP @@ -47,6 +49,11 @@ private var hostTriple: Triple { @Suite(.serialized) struct SwiftPMBuildServerTests { + + init() { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + @Test func testNoPackage() async throws { try await withTestScratchDir { tempDir in diff --git a/Tests/BuildServerProtocolTests/CodingTests.swift b/Tests/BuildServerProtocolTests/CodingTests.swift deleted file mode 100644 index af46c78b1..000000000 --- a/Tests/BuildServerProtocolTests/CodingTests.swift +++ /dev/null @@ -1,70 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import BuildServerProtocol -import Foundation -import LanguageServerProtocol -import SKTestSupport -import XCTest - -final class CodingTests: XCTestCase { - func testMillisecondsSince1970Date() throws { - struct WithDate: Codable, Equatable { - @CustomCodable - var date: Date - } - - checkCoding( - WithDate(date: Date(timeIntervalSince1970: 12.3)), - json: """ - { - "date" : 12300 - } - """ - ) - - // Check that the encoded date is an integer, not a double - checkEncoding( - WithDate(date: Date(timeIntervalSince1970: 12.34567)), - json: """ - { - "date" : 12346 - } - """ - ) - } - - func testOptionalMillisecondsSince1970Date() throws { - struct WithDate: Codable, Equatable { - @CustomCodable - var date: Date? - } - - checkCoding( - WithDate(date: Date(timeIntervalSince1970: 12.3)), - json: """ - { - "date" : 12300 - } - """ - ) - - checkCoding( - WithDate(date: nil), - json: """ - { - - } - """ - ) - } -} diff --git a/Tests/DiagnoseTests/DiagnoseTests.swift b/Tests/DiagnoseTests/DiagnoseTests.swift index 6fc1aa7df..322525263 100644 --- a/Tests/DiagnoseTests/DiagnoseTests.swift +++ b/Tests/DiagnoseTests/DiagnoseTests.swift @@ -12,7 +12,7 @@ @_spi(Testing) import Diagnose import Foundation -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitD import SwiftExtensions @@ -44,6 +44,10 @@ private let sdkArgs: [String] = { }() final class DiagnoseTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testRemoveCodeItemsAndMembers() async throws { // We consider the test case reproducing if cursor info returns the two ambiguous results including their doc // comments. diff --git a/Tests/LanguageServerProtocolJSONRPCTests/CodingTests.swift b/Tests/LanguageServerProtocolJSONRPCTests/CodingTests.swift deleted file mode 100644 index 1e86c4121..000000000 --- a/Tests/LanguageServerProtocolJSONRPCTests/CodingTests.swift +++ /dev/null @@ -1,490 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -@_spi(Testing) import LanguageServerProtocolJSONRPC -import SKTestSupport -import XCTest - -final class CodingTests: XCTestCase { - - func testMessageCoding() { - checkMessageCoding( - InitializeRequest( - processId: 1, - clientInfo: InitializeRequest.ClientInfo(name: "dummy-client", version: "1.0"), - locale: "en-US", - rootPath: "/foo", - rootURI: nil, - initializationOptions: nil, - capabilities: ClientCapabilities(workspace: nil, textDocument: nil), - trace: .off, - workspaceFolders: nil - ), - id: .number(2), - json: """ - { - "id" : 2, - "jsonrpc" : "2.0", - "method" : "initialize", - "params" : { - "capabilities" : { - - }, - "clientInfo" : { - "name" : "dummy-client", - "version" : "1.0" - }, - "locale" : "en-US", - "processId" : 1, - "rootPath" : "/foo", - "trace" : "off" - } - } - """ - ) - - checkMessageCoding( - InitializeRequest( - processId: 1, - rootPath: "/foo", - rootURI: nil, - initializationOptions: nil, - capabilities: ClientCapabilities(workspace: nil, textDocument: nil), - trace: .off, - workspaceFolders: nil - ), - id: .string("3"), - json: """ - { - "id" : "3", - "jsonrpc" : "2.0", - "method" : "initialize", - "params" : { - "capabilities" : { - - }, - "processId" : 1, - "rootPath" : "/foo", - "trace" : "off" - } - } - """ - ) - - checkMessageCoding( - CancelRequestNotification(id: .number(1)), - json: """ - { - "jsonrpc" : "2.0", - "method" : "$/cancelRequest", - "params" : { - "id" : 1 - } - } - """ - ) - - checkMessageCoding( - InitializedNotification(), - json: """ - { - "jsonrpc" : "2.0", - "method" : "initialized", - "params" : { - - } - } - """ - ) - - checkMessageCoding( - InitializeResult( - capabilities: ServerCapabilities( - textDocumentSync: .options( - TextDocumentSyncOptions( - openClose: true, - change: .incremental, - willSave: true, - willSaveWaitUntil: false, - save: .value(TextDocumentSyncOptions.SaveOptions(includeText: false)) - ) - ), - completionProvider: CompletionOptions( - resolveProvider: false, - triggerCharacters: ["."] - ) - ) - ), - id: .number(2), - json: """ - { - "id" : 2, - "jsonrpc" : "2.0", - "result" : { - "capabilities" : { - "completionProvider" : { - "resolveProvider" : false, - "triggerCharacters" : [ - "." - ] - }, - "textDocumentSync" : { - "change" : 2, - "openClose" : true, - "save" : { - "includeText" : false - }, - "willSave" : true, - "willSaveWaitUntil" : false - } - } - } - } - """ - ) - - checkMessageCoding( - ResponseError.cancelled, - id: .number(2), - json: """ - { - "error" : { - "code" : -32800, - "message" : "request cancelled by client" - }, - "id" : 2, - "jsonrpc" : "2.0" - } - """ - ) - - checkMessageCoding( - ResponseError.methodNotFound("asdf"), - id: .number(2), - json: """ - { - "error" : { - "code" : -32601, - "message" : "method not found: asdf" - }, - "id" : 2, - "jsonrpc" : "2.0" - } - """ - ) - - checkMessageCoding( - ResponseError.cancelled, - id: nil, - json: """ - { - "error" : { - "code" : -32800, - "message" : "request cancelled by client" - }, - "id" : null, - "jsonrpc" : "2.0" - } - """ - ) - } - - func testMessageDecodingError() { - // Note: JSON parsing errors are caught at a higher level. - - checkMessageDecodingError( - MessageDecodingError.invalidRequest("jsonrpc version must be 2.0"), - json: """ - {} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest("message not recognized as request, response or notification"), - json: """ - {"jsonrpc":"2.0"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest("message not recognized as request, response or notification"), - json: """ - {"jsonrpc":"2.0","params":{}} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest("message not recognized as request, response or notification"), - json: """ - {"jsonrpc":"2.0","result":{}} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.methodNotFound("unknown", messageKind: .notification), - json: """ - {"jsonrpc":"2.0","method":"unknown"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.methodNotFound("unknown", id: .number(2), messageKind: .request), - json: """ - {"jsonrpc":"2.0","id":2,"method":"unknown"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.methodNotFound("initialized", id: .number(2), messageKind: .request), - json: """ - {"jsonrpc":"2.0","id":2,"method":"initialized"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.methodNotFound("initialize", messageKind: .notification), - json: """ - {"jsonrpc":"2.0","method":"initialize"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidParams("missing expected parameter: params", messageKind: .notification), - json: """ - {"jsonrpc":"2.0","method":"$/cancelRequest"} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidParams("type mismatch at params :", messageKind: .notification), - json: """ - {"jsonrpc":"2.0","method":"$/cancelRequest","params":2} - """ - ) - - checkMessageDecodingError( - MessageDecodingError.invalidParams("missing expected parameter: id", messageKind: .notification), - json: """ - {"jsonrpc":"2.0","method":"$/cancelRequest","params":{}} - """ - ) - - let responseTypeCallback: JSONRPCMessage.ResponseTypeCallback = { - return $0 == .string("unknown") ? nil : InitializeResult.self - } - - var info = defaultCodingInfo - info[CodingUserInfoKey.responseTypeCallbackKey] = responseTypeCallback - - checkMessageDecodingError( - MessageDecodingError.invalidRequest( - "message not recognized as request, response or notification", - id: .number(2) - ), - json: """ - {"jsonrpc":"2.0","id":2,"params":{}} - """, - userInfo: info - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest("message not recognized as request, response or notification"), - json: """ - {"jsonrpc":"2.0","params":{}} - """, - userInfo: info - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest( - "message not recognized as request, response or notification", - id: .string("3") - ), - json: """ - {"jsonrpc":"2.0","id":"3","params":{}} - """, - userInfo: info - ) - - checkMessageDecodingError( - MessageDecodingError.invalidRequest( - "message not recognized as request, response or notification", - id: .string("unknown") - ), - json: """ - {"jsonrpc":"2.0","id":"unknown","params":{}} - """, - userInfo: info - ) - - checkMessageDecodingError( - MessageDecodingError.invalidParams( - "missing expected parameter: capabilities", - id: .number(2), - messageKind: .response - ), - json: """ - {"jsonrpc":"2.0","id":2,"result":{}} - """, - userInfo: info - ) - } - - // SR-16095 - func testDecodeShutdownWithoutParams() throws { - let json = """ - { - "id" : 1, - "jsonrpc" : "2.0", - "method" : "shutdown" - } - """ - - let decoder = JSONDecoder() - decoder.userInfo = defaultCodingInfo - let decodedValue = try decoder.decode(JSONRPCMessage.self, from: json.data(using: .utf8)!) - - guard case JSONRPCMessage.request(let decodedValueOpaque, let decodedID) = decodedValue, - let decodedRequest = decodedValueOpaque as? ShutdownRequest - else { - XCTFail("decodedValue \(decodedValue) is not a ShutdownRequest") - return - } - - XCTAssertEqual(.number(1), decodedID, "expected request ID 1") - XCTAssertEqual(ShutdownRequest(), decodedRequest) - } -} - -let defaultCodingInfo: [CodingUserInfoKey: any Sendable] = [ - CodingUserInfoKey.messageRegistryKey: MessageRegistry.lspProtocol -] - -private func checkMessageCoding( - _ value: Request, - id: RequestID, - json: String, - file: StaticString = #filePath, - line: UInt = #line -) { - checkCoding(JSONRPCMessage.request(value, id: id), json: json, userInfo: defaultCodingInfo, file: file, line: line) { - guard case JSONRPCMessage.request(let decodedValueOpaque, let decodedID) = $0, - let decodedValue = decodedValueOpaque as? Request - else { - XCTFail("decodedValue \($0) does not match expected \(value)", file: file, line: line) - return - } - - XCTAssertEqual(id, decodedID, "requestID decoding", file: file, line: line) - XCTAssertEqual(value, decodedValue, file: file, line: line) - } -} - -private func checkMessageCoding( - _ value: Notification, - json: String, - file: StaticString = #filePath, - line: UInt = #line -) { - checkCoding(JSONRPCMessage.notification(value), json: json, userInfo: defaultCodingInfo, file: file, line: line) { - guard case JSONRPCMessage.notification(let decodedValueOpaque) = $0, - let decodedValue = decodedValueOpaque as? Notification - else { - XCTFail("decodedValue \($0) does not match expected \(value)", file: file, line: line) - return - } - - XCTAssertEqual(value, decodedValue, file: file, line: line) - } -} - -private func checkMessageCoding( - _ value: Response, - id: RequestID, - json: String, - file: StaticString = #filePath, - line: UInt = #line -) { - let callback: JSONRPCMessage.ResponseTypeCallback = { - return $0 == .string("unknown") ? nil : Response.self - } - - var codingInfo = defaultCodingInfo - codingInfo[.responseTypeCallbackKey] = callback - - checkCoding(JSONRPCMessage.response(value, id: id), json: json, userInfo: codingInfo, file: file, line: line) { - - guard case JSONRPCMessage.response(let decodedValueOpaque, let decodedID) = $0, - let decodedValue = decodedValueOpaque as? Response - else { - XCTFail("decodedValue \($0) does not match expected \(value)", file: file, line: line) - return - } - - XCTAssertEqual(id, decodedID, "requestID decoding", file: file, line: line) - XCTAssertEqual(value, decodedValue, file: file, line: line) - } -} - -private func checkMessageCoding( - _ value: ResponseError, - id: RequestID?, - json: String, - file: StaticString = #filePath, - line: UInt = #line -) { - checkCoding( - JSONRPCMessage.errorResponse(value, id: id), - json: json, - userInfo: defaultCodingInfo, - file: file, - line: line - ) { - - guard case JSONRPCMessage.errorResponse(let decodedValue, let decodedID) = $0 else { - XCTFail("decodedValue \($0) does not match expected \(value)", file: file, line: line) - return - } - - XCTAssertEqual(id, decodedID, "requestID decoding", file: file, line: line) - XCTAssertEqual(value, decodedValue, file: file, line: line) - } -} - -private func checkMessageDecodingError( - _ expected: MessageDecodingError, - json: String, - userInfo: [CodingUserInfoKey: any Sendable] = defaultCodingInfo, - file: StaticString = #filePath, - line: UInt = #line -) { - let data = json.data(using: .utf8)! - let decoder = JSONDecoder() - decoder.userInfo = userInfo - - do { - _ = try decoder.decode(JSONRPCMessage.self, from: data) - XCTFail("expected error not seen", file: file, line: line) - } catch let error as MessageDecodingError { - XCTAssertEqual(expected.code, error.code, file: file, line: line) - XCTAssertEqual(expected.id, error.id, file: file, line: line) - XCTAssertTrue( - error.message.hasPrefix(expected.message), - "message expected to start with \(expected.message); got \(error.message)", - file: file, - line: line - ) - } catch { - XCTFail("incorrect error seen \(error)", file: file, line: line) - } -} diff --git a/Tests/LanguageServerProtocolJSONRPCTests/ConnectionPerfTests.swift b/Tests/LanguageServerProtocolJSONRPCTests/ConnectionPerfTests.swift deleted file mode 100644 index f13587e05..000000000 --- a/Tests/LanguageServerProtocolJSONRPCTests/ConnectionPerfTests.swift +++ /dev/null @@ -1,73 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocolJSONRPC -import SKTestSupport -import XCTest - -class ConnectionPerfTests: PerfTestCase { - - var connection: TestJSONRPCConnection! = nil - - override func setUp() { - connection = TestJSONRPCConnection() - } - - override func tearDown() { - connection.close() - } - - func testEcho1() { - let client = connection.client - self.measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) { - let expectation = self.expectation(description: "response received") - self.startMeasuring() - _ = client.send(EchoRequest(string: "hello!")) { _ in - expectation.fulfill() - } - - wait(for: [expectation], timeout: defaultTimeout) - self.stopMeasuring() - } - } - - func testEcho100Latency() { - let client = connection.client - let sema = DispatchSemaphore(value: 0) - self.measure { - for _ in 1...100 { - _ = client.send(EchoRequest(string: "hello!")) { _ in - sema.signal() - } - XCTAssertEqual(sema.wait(timeout: .now() + .seconds(Int(defaultTimeout))), .success) - } - } - } - - func testEcho100Throughput() { - let client = connection.client - let sema = DispatchSemaphore(value: 0) - self.measure { - DispatchQueue.concurrentPerform( - iterations: 100, - execute: { _ in - _ = client.send(EchoRequest(string: "hello!")) { _ in - sema.signal() - } - } - ) - for _ in 1...100 { - XCTAssertEqual(sema.wait(timeout: .now() + .seconds(Int(defaultTimeout))), .success) - } - } - } -} diff --git a/Tests/LanguageServerProtocolJSONRPCTests/ConnectionTests.swift b/Tests/LanguageServerProtocolJSONRPCTests/ConnectionTests.swift deleted file mode 100644 index 69a1113d2..000000000 --- a/Tests/LanguageServerProtocolJSONRPCTests/ConnectionTests.swift +++ /dev/null @@ -1,314 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -@_spi(Testing) import LanguageServerProtocolJSONRPC -import SKTestSupport -import XCTest - -import class Foundation.Pipe - -#if os(Windows) -import WinSDK -#elseif canImport(Android) -import Android -#endif - -class ConnectionTests: XCTestCase { - - var connection: TestJSONRPCConnection! = nil - - override func setUp() { - connection = TestJSONRPCConnection(allowUnexpectedNotification: false) - } - - override func tearDown() { - connection.close() - } - - func testRound() throws { - let enc = try JSONEncoder().encode(EchoRequest(string: "a/b")) - let dec = try JSONDecoder().decode(EchoRequest.self, from: enc) - XCTAssertEqual("a/b", dec.string) - } - - func testEcho() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received") - - _ = client.send(EchoRequest(string: "hello!")) { resp in - assertNoThrow { - XCTAssertEqual(try resp.get(), "hello!") - } - expectation.fulfill() - } - - try await fulfillmentOfOrThrow(expectation) - } - - func testMessageBuffer() async throws { - let client = connection.client - let clientConnection = connection.clientToServerConnection - let expectation = self.expectation(description: "notfication received") - - await client.appendOneShotNotificationHandler { (notification: EchoNotification) in - XCTAssertEqual(notification.string, "hello!") - expectation.fulfill() - } - - let notification1 = try JSONEncoder().encode(JSONRPCMessage.notification(EchoNotification(string: "hello!"))) - let notification2 = try JSONEncoder().encode(JSONRPCMessage.notification(EchoNotification(string: "no way!"))) - - let notification1Str = - "Content-Length: \(notification1.count)\r\n\r\n\(String(data: notification1, encoding: .utf8)!)" - let notfication2Str = - "Content-Length: \(notification2.count)\r\n\r\n\(String(data: notification2, encoding: .utf8)!)" - - for b in notification1Str.utf8.dropLast() { - clientConnection.send(_rawData: [b].withUnsafeBytes { DispatchData(bytes: $0) }) - } - - clientConnection.send( - _rawData: [notification1Str.utf8.last!, notfication2Str.utf8.first!].withUnsafeBytes { DispatchData(bytes: $0) } - ) - - try await fulfillmentOfOrThrow(expectation) - - let expectation2 = self.expectation(description: "notification received") - - await client.appendOneShotNotificationHandler { (notification: EchoNotification) in - XCTAssertEqual(notification.string, "no way!") - expectation2.fulfill() - } - - for b in notfication2Str.utf8.dropFirst() { - clientConnection.send(_rawData: [b].withUnsafeBytes { DispatchData(bytes: $0) }) - } - - try await fulfillmentOfOrThrow(expectation2) - - // Close the connection before accessing requestBuffer, which ensures we don't race. - connection.serverToClientConnection.close() - XCTAssert(connection.serverToClientConnection.requestBufferIsEmpty) - } - - func testEchoError() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received 1") - let expectation2 = self.expectation(description: "response received 2") - - _ = client.send(EchoError(code: nil)) { (resp) -> Void in - do { - assertNoThrow { - XCTAssertEqual(try resp.get(), VoidResponse()) - } - } - expectation.fulfill() - } - - _ = client.send(EchoError(code: .unknownErrorCode, message: "hey!")) { resp in - XCTAssertEqual(resp, LSPResult.failure(ResponseError(code: .unknownErrorCode, message: "hey!"))) - expectation2.fulfill() - } - - try await fulfillmentOfOrThrow(expectation, expectation2) - } - - func testEchoNotification() async throws { - let client = connection.client - let expectation = self.expectation(description: "notification received") - - await client.appendOneShotNotificationHandler { (notification: EchoNotification) in - XCTAssertEqual(notification.string, "hello!") - expectation.fulfill() - } - - client.send(EchoNotification(string: "hello!")) - - try await fulfillmentOfOrThrow(expectation) - } - - func testUnknownRequest() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received") - - struct UnknownRequest: RequestType { - static let method: String = "unknown" - typealias Response = VoidResponse - } - - _ = client.send(UnknownRequest()) { result in - XCTAssertEqual(result, .failure(ResponseError.methodNotFound("unknown"))) - expectation.fulfill() - } - - try await fulfillmentOfOrThrow(expectation) - } - - func testUnknownNotification() async throws { - let client = connection.client - let expectation = self.expectation(description: "notification received") - - struct UnknownNotification: NotificationType { - static let method: String = "unknown" - } - - client.send(UnknownNotification()) - - // Nothing bad should happen; check that the next request works. - - _ = client.send(EchoRequest(string: "hello!")) { resp in - assertNoThrow { - XCTAssertEqual(try resp.get(), "hello!") - } - expectation.fulfill() - } - - try await fulfillmentOfOrThrow(expectation) - } - - func testUnexpectedResponse() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received") - - // response to unknown request - connection.clientToServerConnection.sendReply(.success(VoidResponse()), id: .string("unknown")) - - // Nothing bad should happen; check that the next request works. - - _ = client.send(EchoRequest(string: "hello!")) { resp in - assertNoThrow { - XCTAssertEqual(try resp.get(), "hello!") - } - expectation.fulfill() - } - - try await fulfillmentOfOrThrow(expectation) - } - - func testSendAfterClose() async throws { - let client = connection.client - let expectation = self.expectation(description: "notification received") - - connection.clientToServerConnection.close() - - client.send(EchoNotification(string: "hi")) - _ = client.send(EchoRequest(string: "yo")) { result in - XCTAssertEqual(result, .failure(ResponseError.serverCancelled)) - expectation.fulfill() - } - - connection.clientToServerConnection.sendReply(.success(VoidResponse()), id: .number(1)) - - connection.clientToServerConnection.close() - connection.clientToServerConnection.close() - - try await fulfillmentOfOrThrow(expectation) - } - - func testSendBeforeClose() async throws { - let client = connection.client - let server = connection.server - - let expectation = self.expectation(description: "received notification") - await client.appendOneShotNotificationHandler { (notification: EchoNotification) in - expectation.fulfill() - } - - server.client.send(EchoNotification(string: "about to close!")) - connection.serverToClientConnection.close() - - try await fulfillmentOfOrThrow(expectation) - } - - /// We can explicitly close a connection, but the connection also - /// automatically closes itself if the pipe is closed (or has an error). - /// DispatchIO can make its callback at any time, so this test is to try to - /// provoke a race between those things and ensure the closeHandler is called - /// exactly once. - func testCloseRace() async throws { - for _ in 0...100 { - let to = Pipe() - let from = Pipe() - let expectation = self.expectation(description: "closed") - expectation.assertForOverFulfill = true - - let conn = JSONRPCConnection( - name: "test", - protocol: MessageRegistry(requests: [], notifications: []), - inFD: to.fileHandleForReading, - outFD: from.fileHandleForWriting - ) - - final class DummyHandler: MessageHandler { - func handle(_: some NotificationType) {} - func handle( - _ request: Request, - id: RequestID, - reply: @escaping (LSPResult) -> Void - ) {} - } - - conn.start( - receiveHandler: DummyHandler(), - closeHandler: { - // We get an error from XCTest if this is fulfilled more than once. - expectation.fulfill() - - // Keep the pipes alive until we close the connection. - withExtendedLifetime((to, from)) {} - } - ) - - to.fileHandleForWriting.closeFile() - #if os(Windows) - // 1 ms was chosen for simplicity. - Sleep(1) - #else - // 100 us was chosen empirically to encourage races. - usleep(100) - #endif - conn.close() - - try await fulfillmentOfOrThrow(expectation) - withExtendedLifetime(conn) {} - } - } - - func testMessageWithMissingParameter() async throws { - let expectation = self.expectation(description: "Received ShowMessageNotification") - await connection.client.appendOneShotNotificationHandler { (notification: ShowMessageNotification) in - XCTAssertEqual(notification.type, .error) - expectation.fulfill() - } - - let messageContents = """ - { - "method": "test_server/echo_note", - "jsonrpc": "2.0", - "params": {} - } - """ - connection.clientToServerConnection.send(message: messageContents) - - try await fulfillmentOfOrThrow(expectation) - } -} - -fileprivate extension JSONRPCConnection { - func send(message: String) { - let messageWithHeader = "Content-Length: \(message.utf8.count)\r\n\r\n\(message)".data(using: .utf8)! - messageWithHeader.withUnsafeBytes { bytes in - send(_rawData: DispatchData(bytes: bytes)) - } - } -} diff --git a/Tests/LanguageServerProtocolJSONRPCTests/MessageParsingTests.swift b/Tests/LanguageServerProtocolJSONRPCTests/MessageParsingTests.swift deleted file mode 100644 index b30195341..000000000 --- a/Tests/LanguageServerProtocolJSONRPCTests/MessageParsingTests.swift +++ /dev/null @@ -1,233 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -@_spi(Testing) import LanguageServerProtocolJSONRPC -import XCTest - -final class MessageParsingTests: XCTestCase { - - func testSplitMessage() throws { - func check( - _ string: String, - contentLen: Int? = nil, - restLen: Int?, - file: StaticString = #filePath, - line: UInt = #line - ) throws { - let bytes: [UInt8] = [UInt8](string.utf8) - guard let (header, content, rest) = try bytes.jsonrpcSplitMessage() else { - XCTAssert(restLen == nil, "expected non-empty field", file: file, line: line) - return - } - XCTAssertEqual(rest.count, restLen, "rest", file: file, line: line) - XCTAssertEqual(content.count, contentLen, "content", file: file, line: line) - XCTAssertEqual(header.contentLength, contentLen, file: file, line: line) - } - - func checkError( - _ string: String, - _ expected: MessageDecodingError, - file: StaticString = #filePath, - line: UInt = #line - ) { - do { - _ = try [UInt8](string.utf8).jsonrpcSplitMessage() - XCTFail("missing expected error", file: file, line: line) - } catch let error as MessageDecodingError { - XCTAssertEqual(error, expected, file: file, line: line) - } catch { - XCTFail("error \(error) does not match expected \(expected)", file: file, line: line) - } - } - - try check("Content-Length: 2\r\n", restLen: nil) - try check("Content-Length: 1\r\n\r\n", restLen: nil) - try check("Content-Length: 2\r\n\r\n{", restLen: nil) - - try check("Content-Length: 0\r\n\r\n", contentLen: 0, restLen: 0) - try check("Content-Length: 0\r\n\r\n{}", contentLen: 0, restLen: 2) - try check("Content-Length: 1\r\n\r\n{}", contentLen: 1, restLen: 1) - try check("Content-Length: 2\r\n\r\n{}", contentLen: 2, restLen: 0) - try check("Content-Length: 2\r\n\r\n{}Co", contentLen: 2, restLen: 2) - - checkError("\r\n\r\n{}", MessageDecodingError.parseError("missing Content-Length header")) - } - - func testParseHeader() throws { - func check( - _ string: String, - header expected: JSONRPCMessageHeader? = nil, - restLen: Int?, - file: StaticString = #filePath, - line: UInt = #line - ) throws { - let bytes: [UInt8] = [UInt8](string.utf8) - guard let (header, rest) = try bytes.jsonrcpParseHeader() else { - XCTAssert(restLen == nil, "expected non-empty field", file: file, line: line) - return - } - XCTAssertEqual(rest.count, restLen, "rest", file: file, line: line) - XCTAssertEqual(header, expected, file: file, line: line) - } - - func checkErrorBytes( - _ bytes: [UInt8], - _ expected: MessageDecodingError, - file: StaticString = #filePath, - line: UInt = #line - ) { - do { - _ = try bytes.jsonrcpParseHeader() - XCTFail("missing expected error", file: file, line: line) - } catch let error as MessageDecodingError { - XCTAssertEqual(error, expected, file: file, line: line) - } catch { - XCTFail("error \(error) does not match expected \(expected)", file: file, line: line) - } - } - - func checkError( - _ string: String, - _ expected: MessageDecodingError, - file: StaticString = #filePath, - line: UInt = #line - ) { - checkErrorBytes([UInt8](string.utf8), expected, file: file, line: line) - } - - try check("", restLen: nil) - try check("C", restLen: nil) - try check("Content-Length: 1", restLen: nil) - try check("Content-Length: 1\r", restLen: nil) - try check("Content-Length: 1\r\n", restLen: nil) - try check("Content-Length: 1\r\n\r\n", header: JSONRPCMessageHeader(contentLength: 1), restLen: 0) - try check("Content-Length: 1\r\n\r\n{}", header: JSONRPCMessageHeader(contentLength: 1), restLen: 2) - try check("A:B\r\nContent-Length: 1\r\nC:D\r\n\r\n", header: JSONRPCMessageHeader(contentLength: 1), restLen: 0) - try check("Content-Length:123 \r\n\r\n", header: JSONRPCMessageHeader(contentLength: 123), restLen: 0) - - checkError("Content-Length:0x1\r\n\r\n", MessageDecodingError.parseError("expected integer value in 0x1")) - checkError("Content-Length:a123\r\n\r\n", MessageDecodingError.parseError("expected integer value in a123")) - - checkErrorBytes( - [UInt8]("Content-Length: ".utf8) + [0xFF] + [UInt8]("\r\n".utf8), - MessageDecodingError.parseError("expected integer value in ") - ) - } - - func testParseHeaderField() throws { - func check( - _ string: String, - keyLen: Int? = nil, - valueLen: Int? = nil, - restLen: Int?, - file: StaticString = #filePath, - line: UInt = #line - ) throws { - let bytes: [UInt8] = [UInt8](string.utf8) - guard let (kv, rest) = try bytes.jsonrpcParseHeaderField() else { - XCTAssert(restLen == nil, "expected non-empty field", file: file, line: line) - return - } - XCTAssertEqual(rest.count, restLen, "rest", file: file, line: line) - XCTAssertEqual(kv?.key.count, keyLen, "key", file: file, line: line) - if let key = kv?.key { - XCTAssertEqual(key, bytes.prefix(key.count), file: file, line: line) - } - XCTAssertEqual(kv?.value.count, valueLen, "value", file: file, line: line) - if let value = kv?.value { - XCTAssertEqual(value, bytes.dropFirst(kv!.key.count + 1).prefix(value.count), file: file, line: line) - } - } - - func checkError( - _ string: String, - _ expected: MessageDecodingError, - file: StaticString = #filePath, - line: UInt = #line - ) { - do { - _ = try [UInt8](string.utf8).jsonrpcParseHeaderField() - XCTFail("missing expected error", file: file, line: line) - } catch let error as MessageDecodingError { - XCTAssertEqual(error, expected, file: file, line: line) - } catch { - XCTFail("error \(error) does not match expected \(expected)", file: file, line: line) - } - } - - try check("", restLen: nil) - try check("C", restLen: nil) - try check("Content-Length", restLen: nil) - try check("Content-Length:", restLen: nil) - try check("Content-Length:a", restLen: nil) - try check("Content-Length: 1", restLen: nil) - try check("Content-Length: 1\r", restLen: nil) - try check("Content-Length: 1\r\n", keyLen: "Content-Length".count, valueLen: 2, restLen: 0) - try check("Content-Length:1\r\n", keyLen: "Content-Length".count, valueLen: 1, restLen: 0) - try check("Content-Length: 1\r\n ", keyLen: "Content-Length".count, valueLen: 2, restLen: 1) - try check("Content-Length: 1\r\n\r\n", keyLen: "Content-Length".count, valueLen: 2, restLen: 2) - try check("Unknown:asdf\r", restLen: nil) - try check("Unknown:asdf\r\n", keyLen: "Unknown".count, valueLen: 4, restLen: 0) - try check("\r", restLen: nil) - try check("\r\n", restLen: 0) - try check("\r\nC", restLen: 1) - try check("\r\nContent-Length:1\r\n", restLen: "Content-Length:1\r\n".utf8.count) - try check(":", restLen: nil) - try check(":\r\n", keyLen: 0, valueLen: 0, restLen: 0) - - checkError("C\r\n", MessageDecodingError.parseError("expected ':' in message header")) - } - - func testIntFromAscii() { - XCTAssertNil(Int(ascii: "")) - XCTAssertNil(Int(ascii: "a")) - XCTAssertNil(Int(ascii: "0x1")) - XCTAssertNil(Int(ascii: " ")) - XCTAssertNil(Int(ascii: "+")) - XCTAssertNil(Int(ascii: "-")) - XCTAssertNil(Int(ascii: "+ ")) - XCTAssertNil(Int(ascii: "- ")) - XCTAssertNil(Int(ascii: "1 1")) - XCTAssertNil(Int(ascii: "1a1")) - XCTAssertNil(Int(ascii: "1a")) - XCTAssertNil(Int(ascii: "1+")) - XCTAssertNil(Int(ascii: "+ 1")) - XCTAssertNil(Int(ascii: "- 1")) - XCTAssertNil(Int(ascii: "1-1")) - - XCTAssertEqual(Int(ascii: "0"), 0) - XCTAssertEqual(Int(ascii: "1"), 1) - XCTAssertEqual(Int(ascii: "45"), 45) - XCTAssertEqual(Int(ascii: " 45 "), 45) - XCTAssertEqual(Int(ascii: "\(Int.max)"), Int.max) - XCTAssertEqual(Int(ascii: "\(Int.max-1)"), Int.max - 1) - XCTAssertEqual(Int(ascii: "\(Int.min)"), Int.min) - XCTAssertEqual(Int(ascii: "\(Int.min+1)"), Int.min + 1) - - XCTAssertEqual(Int(ascii: "+0"), 0) - XCTAssertEqual(Int(ascii: "+1"), 1) - XCTAssertEqual(Int(ascii: "+45"), 45) - XCTAssertEqual(Int(ascii: " +45 "), 45) - XCTAssertEqual(Int(ascii: "-0"), 0) - XCTAssertEqual(Int(ascii: "-1"), -1) - XCTAssertEqual(Int(ascii: "-45"), -45) - XCTAssertEqual(Int(ascii: " -45 "), -45) - XCTAssertEqual(Int(ascii: "+\(Int.max)"), Int.max) - XCTAssertEqual(Int(ascii: "+\(Int.max-1)"), Int.max - 1) - XCTAssertEqual(Int(ascii: "\(Int.min)"), Int.min) - XCTAssertEqual(Int(ascii: "\(Int.min+1)"), Int.min + 1) - - XCTAssertEqual(Int(ascii: "1234567890"), 1_234_567_890) - XCTAssertEqual(Int(ascii: "\n\r \u{b}\u{d}\t45\n\t\r\u{c}"), 45) - } -} diff --git a/Tests/LanguageServerProtocolTests/CodingTests.swift b/Tests/LanguageServerProtocolTests/CodingTests.swift deleted file mode 100644 index fe7dc655f..000000000 --- a/Tests/LanguageServerProtocolTests/CodingTests.swift +++ /dev/null @@ -1,1408 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -import SKTestSupport -import XCTest - -final class CodingTests: XCTestCase { - - func testValueCoding() throws { - let url = URL(fileURLWithPath: "/foo.swift") - let uri = DocumentURI(url) - let urljson = "file:///foo.swift" - - let range = Position(line: 5, utf16index: 23).. start, Range.upperBound -> end - let rangejson = """ - { - "end" : { - "character" : 0, - "line" : 6 - }, - "start" : { - "character" : 23, - "line" : 5 - } - } - """ - - let indent2rangejson = rangejson.indented(2, skipFirstLine: true) - - // url -> uri - checkCoding( - Location(uri: uri, range: range), - json: """ - { - "range" : \(indent2rangejson), - "uri" : "\(urljson)" - } - """ - ) - - checkCoding( - TextEdit(range: range, newText: "foo"), - json: """ - { - "newText" : "foo", - "range" : \(indent2rangejson) - } - """ - ) - - // url -> uri - checkCoding( - TextDocumentIdentifier(uri), - json: """ - { - "uri" : "\(urljson)" - } - """ - ) - - checkCoding( - OptionalVersionedTextDocumentIdentifier(uri, version: nil), - json: """ - { - "uri" : "\(urljson)", - "version" : null - } - """ - ) - - checkCoding( - VersionedTextDocumentIdentifier(uri, version: 3), - json: """ - { - "uri" : "\(urljson)", - "version" : 3 - } - """ - ) - - checkCoding( - TextDocumentEdit( - textDocument: OptionalVersionedTextDocumentIdentifier(uri, version: 1), - edits: [ - .textEdit(TextEdit(range: range, newText: "foo")) - ] - ), - json: """ - { - "edits" : [ - { - "newText" : "foo", - "range" : \(rangejson.indented(6, skipFirstLine: true)) - } - ], - "textDocument" : { - "uri" : "\(urljson)", - "version" : 1 - } - } - """ - ) - - // url -> uri - checkCoding( - WorkspaceFolder(uri: uri, name: "foo"), - json: """ - { - "name" : "foo", - "uri" : "\(urljson)" - } - """ - ) - - checkCoding( - WorkspaceFolder(uri: uri), - json: """ - { - "name" : "foo.swift", - "uri" : "\(urljson)" - } - """ - ) - - checkCoding( - WorkspaceFolder(uri: uri, name: ""), - json: """ - { - "name" : "unknown_workspace", - "uri" : "\(urljson)" - } - """ - ) - - checkCoding(MarkupKind.markdown, json: "\"markdown\"") - checkCoding(MarkupKind.plaintext, json: "\"plaintext\"") - - checkCoding(SymbolKind.file, json: "1") - checkCoding(SymbolKind.class, json: "5") - - checkCoding(CompletionItemKind.text, json: "1") - checkCoding(CompletionItemKind.class, json: "7") - - checkCoding(CodeActionKind.quickFix, json: "\"quickfix\"") - checkCoding(CodeActionKind(rawValue: "x"), json: "\"x\"") - - checkCoding(ErrorCode.cancelled, json: "-32800") - - checkCoding(ClientCapabilities(workspace: nil, textDocument: nil), json: "{\n\n}") - - checkCoding( - ClientCapabilities( - workspace: with(WorkspaceClientCapabilities()) { $0.applyEdit = true }, - textDocument: nil - ), - json: """ - { - "workspace" : { - "applyEdit" : true - } - } - """ - ) - - checkCoding( - WorkspaceSettingsChange.clangd(ClangWorkspaceSettings(compilationDatabasePath: "foo")), - json: """ - { - "compilationDatabasePath" : "foo" - } - """ - ) - - checkDecoding( - json: """ - { - "hi": "there" - } - """, - expected: WorkspaceSettingsChange.unknown(LSPAny.dictionary(["hi": LSPAny.string("there")])) - ) - - // experimental can be anything - checkDecoding( - json: """ - { - "experimenal": [1] - } - """, - expected: ClientCapabilities(workspace: nil, textDocument: nil) - ) - - checkDecoding( - json: """ - { - "workspace": { - "workspaceEdit": { - "documentChanges": false - } - } - } - """, - expected: ClientCapabilities( - workspace: with(WorkspaceClientCapabilities()) { - $0.workspaceEdit = WorkspaceClientCapabilities.WorkspaceEdit(documentChanges: false) - }, - textDocument: nil - ) - ) - - // ignore unknown keys - checkDecoding( - json: """ - { - "workspace": { - "workspaceEdit": { - "ben's unlikley opton": false - } - } - } - """, - expected: ClientCapabilities( - workspace: with(WorkspaceClientCapabilities()) { - $0.workspaceEdit = WorkspaceClientCapabilities.WorkspaceEdit(documentChanges: nil) - }, - textDocument: nil - ) - ) - - checkCoding(RequestID.number(100), json: "100") - checkCoding(RequestID.string("100"), json: "\"100\"") - - checkCoding(Language.c, json: "\"c\"") - checkCoding(Language.cpp, json: "\"cpp\"") - checkCoding(Language.objective_c, json: "\"objective-c\"") - checkCoding(Language.objective_cpp, json: "\"objective-cpp\"") - checkCoding(Language.swift, json: "\"swift\"") - checkCoding(Language(rawValue: "unknown"), json: "\"unknown\"") - - checkCoding(DiagnosticCode.number(123), json: "123") - checkCoding(DiagnosticCode.string("hi"), json: "\"hi\"") - - checkCoding( - CodeDescription(href: try DocumentURI(string: "file:///some/path")), - json: """ - { - "href" : "file:///some/path" - } - """ - ) - - let markup = MarkupContent(kind: .plaintext, value: "a") - checkCoding( - HoverResponse(contents: .markupContent(markup), range: nil), - json: """ - { - "contents" : { - "kind" : "plaintext", - "value" : "a" - } - } - """ - ) - - checkDecoding( - json: """ - { - "contents" : "test" - } - """, - expected: HoverResponse(contents: .markedStrings([.markdown(value: "test")]), range: nil) - ) - - checkCoding( - HoverResponse( - contents: .markedStrings([.markdown(value: "test"), .codeBlock(language: "swift", value: "let foo = 2")]), - range: nil - ), - json: """ - { - "contents" : [ - "test", - { - "language" : "swift", - "value" : "let foo = 2" - } - ] - } - """ - ) - - checkCoding( - HoverResponse(contents: .markupContent(markup), range: range), - json: """ - { - "contents" : { - "kind" : "plaintext", - "value" : "a" - }, - "range" : \(rangejson.indented(2, skipFirstLine: true)) - } - """ - ) - - checkCoding( - TextDocumentContentChangeEvent(text: "a"), - json: """ - { - "text" : "a" - } - """ - ) - checkCoding( - TextDocumentContentChangeEvent(range: range, rangeLength: 10, text: "a"), - json: """ - { - "range" : \(rangejson.indented(2, skipFirstLine: true)), - "rangeLength" : 10, - "text" : "a" - } - """ - ) - checkCoding( - WorkspaceEdit(changes: [uri: []]), - json: """ - { - "changes" : { - "\(urljson)" : [ - - ] - } - } - """ - ) - - checkCoding( - CompletionList(isIncomplete: true, items: [CompletionItem(label: "abc", kind: .function)]), - json: """ - { - "isIncomplete" : true, - "items" : [ - { - "kind" : 3, - "label" : "abc" - } - ] - } - """ - ) - - checkDecoding( - json: """ - [ - { - "kind" : 3, - "label" : "abc" - } - ] - """, - expected: CompletionList(isIncomplete: false, items: [CompletionItem(label: "abc", kind: .function)]) - ) - - checkCoding( - StringOrMarkupContent.markupContent(MarkupContent(kind: .markdown, value: "some **Markdown***")), - json: """ - { - "kind" : "markdown", - "value" : "some **Markdown***" - } - """ - ) - - checkCoding( - StringOrMarkupContent.string("Some documentation"), - json: """ - "Some documentation" - """ - ) - - checkCoding(PrepareRenameResponse(range: range), json: rangejson) - - checkCoding( - PrepareRenameResponse(range: range, placeholder: "somePlaceholder"), - json: """ - { - "placeholder" : "somePlaceholder", - "range" : \(rangejson.indented(2, skipFirstLine: true)) - } - """ - ) - - checkCoding( - LocationsOrLocationLinksResponse.locations([Location(uri: uri, range: range)]), - json: """ - [ - { - "range" : \(rangejson.indented(4, skipFirstLine: true)), - "uri" : "\(urljson)" - } - ] - """ - ) - - checkCoding( - LocationsOrLocationLinksResponse.locationLinks([ - LocationLink(targetUri: uri, targetRange: range, targetSelectionRange: range) - ]), - json: """ - [ - { - "targetRange" : \(rangejson.indented(4, skipFirstLine: true)), - "targetSelectionRange" : \(rangejson.indented(4, skipFirstLine: true)), - "targetUri" : "\(urljson)" - } - ] - """ - ) - - checkDecoding( - json: """ - { - "range" : \(rangejson.indented(2, skipFirstLine: true)), - "uri" : "\(urljson)" - } - """, - expected: LocationsOrLocationLinksResponse.locations([Location(uri: uri, range: range)]) - ) - - checkCoding( - DocumentSymbolResponse.documentSymbols([ - DocumentSymbol(name: "mySymbol", kind: .function, range: range, selectionRange: range) - ]), - json: """ - [ - { - "kind" : 12, - "name" : "mySymbol", - "range" : \(rangejson.indented(4, skipFirstLine: true)), - "selectionRange" : \(rangejson.indented(4, skipFirstLine: true)) - } - ] - """ - ) - - checkCoding( - DocumentSymbolResponse.symbolInformation([ - SymbolInformation(name: "mySymbol", kind: .function, location: Location(uri: uri, range: range)) - ]), - json: """ - [ - { - "kind" : 12, - "location" : { - "range" : \(rangejson.indented(6, skipFirstLine: true)), - "uri" : "\(urljson)" - }, - "name" : "mySymbol" - } - ] - """ - ) - - checkCoding(ValueOrBool.value(5), json: "5") - checkCoding(ValueOrBool.bool(false), json: "false") - - checkDecoding( - json: "2", - expected: TextDocumentSyncOptions( - openClose: nil, - change: .incremental, - willSave: nil, - willSaveWaitUntil: nil, - save: nil - ) - ) - - checkCoding( - TextDocumentSyncOptions(), - json: """ - { - "change" : 2, - "openClose" : true, - "save" : { - "includeText" : false - }, - "willSave" : true, - "willSaveWaitUntil" : false - } - """ - ) - - checkCoding( - WorkspaceEdit(documentChanges: [ - .textDocumentEdit( - TextDocumentEdit(textDocument: OptionalVersionedTextDocumentIdentifier(uri, version: 2), edits: []) - ) - ]), - json: """ - { - "documentChanges" : [ - { - "edits" : [ - - ], - "textDocument" : { - "uri" : "\(urljson)", - "version" : 2 - } - } - ] - } - """ - ) - checkCoding( - WorkspaceEdit(documentChanges: [.createFile(CreateFile(uri: uri))]), - json: """ - { - "documentChanges" : [ - { - "kind" : "create", - "uri" : "\(urljson)" - } - ] - } - """ - ) - checkCoding( - WorkspaceEdit(documentChanges: [.renameFile(RenameFile(oldUri: uri, newUri: uri))]), - json: """ - { - "documentChanges" : [ - { - "kind" : "rename", - "newUri" : "\(urljson)", - "oldUri" : "\(urljson)" - } - ] - } - """ - ) - checkCoding( - WorkspaceEdit(documentChanges: [.deleteFile(DeleteFile(uri: uri))]), - json: """ - { - "documentChanges" : [ - { - "kind" : "delete", - "uri" : "\(urljson)" - } - ] - } - """ - ) - - } - - func testValueOrBool() { - XCTAssertTrue(ValueOrBool.value(5).isSupported) - XCTAssertTrue(ValueOrBool.value(0).isSupported) - XCTAssertTrue(ValueOrBool.bool(true).isSupported) - XCTAssertFalse(ValueOrBool.bool(false).isSupported) - } - - func testPositionRange() { - struct WithPosRange: Codable, Equatable { - @CustomCodable - var range: Range - } - - let range = Position(line: 5, utf16index: 23).. - var ranges: [Range] - } - let ranges = [ - Position(line: 1, utf16index: 0).. - var range: Range? - } - - let range = Position(line: 5, utf16index: 23)..(_ value: T, mutate: (inout T) -> Void) -> T { - var localCopy = value - mutate(&localCopy) - return localCopy -} - -extension String { - func indented(_ spaces: Int, skipFirstLine: Bool = false) -> String { - let spaces = String(repeating: " ", count: spaces) - return (skipFirstLine ? "" : spaces) + self.replacingOccurrences(of: "\n", with: "\n" + spaces) - } -} diff --git a/Tests/LanguageServerProtocolTests/ConnectionTests.swift b/Tests/LanguageServerProtocolTests/ConnectionTests.swift deleted file mode 100644 index bfe489a2e..000000000 --- a/Tests/LanguageServerProtocolTests/ConnectionTests.swift +++ /dev/null @@ -1,76 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -import SKTestSupport -import XCTest - -class ConnectionTests: XCTestCase { - - var connection: TestLocalConnection! = nil - - override func setUp() { - connection = TestLocalConnection(allowUnexpectedNotification: false) - } - - override func tearDown() { - connection.close() - } - - func testEcho() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received") - - _ = client.send(EchoRequest(string: "hello!")) { resp in - assertNoThrow { - XCTAssertEqual(try resp.get(), "hello!") - } - expectation.fulfill() - } - - try await fulfillmentOfOrThrow(expectation) - } - - func testEchoError() async throws { - let client = connection.client - let expectation = self.expectation(description: "response received 1") - let expectation2 = self.expectation(description: "response received 2") - - _ = client.send(EchoError(code: nil)) { resp in - assertNoThrow { - XCTAssertEqual(try resp.get(), VoidResponse()) - } - expectation.fulfill() - } - - _ = client.send(EchoError(code: .unknownErrorCode, message: "hey!")) { resp in - XCTAssertEqual(resp, LSPResult.failure(ResponseError(code: .unknownErrorCode, message: "hey!"))) - expectation2.fulfill() - } - - try await fulfillmentOfOrThrow(expectation, expectation2) - } - - func testEchoNotification() async throws { - let client = connection.client - let expectation = self.expectation(description: "notification received") - - await client.appendOneShotNotificationHandler { (notification: EchoNotification) in - XCTAssertEqual(notification.string, "hello!") - expectation.fulfill() - } - - client.send(EchoNotification(string: "hello!")) - - try await fulfillmentOfOrThrow(expectation) - } -} diff --git a/Tests/LanguageServerProtocolTests/LanguageServerProtocolTests.swift b/Tests/LanguageServerProtocolTests/LanguageServerProtocolTests.swift deleted file mode 100644 index 24a730b16..000000000 --- a/Tests/LanguageServerProtocolTests/LanguageServerProtocolTests.swift +++ /dev/null @@ -1,53 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import LanguageServerProtocol -import XCTest - -private func assertDataIsString( - _ data: Data, - expected: String, - file: StaticString = #filePath, - line: UInt = #line -) { - let got = String(decoding: data, as: UTF8.self) - XCTAssertEqual(got, expected, "data not equal to string", file: file, line: line) -} - -final class LanguageServerProtocolTests: XCTestCase { - - func testLanguageXFlag() { - XCTAssertEqual(Language.c.xflag, "c") - XCTAssertEqual(Language.c.xflagHeader, "c-header") - XCTAssertEqual(Language.cpp.xflag, "c++") - XCTAssertEqual(Language.cpp.xflagHeader, "c++-header") - XCTAssertEqual(Language.objective_c.xflag, "objective-c") - XCTAssertEqual(Language.objective_c.xflagHeader, "objective-c-header") - XCTAssertEqual(Language.objective_cpp.xflag, "objective-c++") - XCTAssertEqual(Language.objective_cpp.xflagHeader, "objective-c++-header") - } - - func testURLEscaping() throws { - let fileURI = DocumentURI(URL(fileURLWithPath: "/folder/image@3x.png", isDirectory: false)) - let encodedURI = try DocumentURI(string: "file:///folder/image%403x.png") - XCTAssertEqual(encodedURI, fileURI) - XCTAssertEqual(encodedURI.hashValue, fileURI.hashValue) - } - - func testFileChangeTypeEncoding() throws { - let encoder = JSONEncoder() - try assertDataIsString(encoder.encode(FileChangeType.created), expected: "1") - try assertDataIsString(encoder.encode(FileChangeType.changed), expected: "2") - try assertDataIsString(encoder.encode(FileChangeType.deleted), expected: "3") - try assertDataIsString(encoder.encode(FileChangeType(rawValue: 5)), expected: "5") - } -} diff --git a/Tests/SKLoggingTests/LoggingTests.swift b/Tests/SKLoggingTests/LoggingTests.swift deleted file mode 100644 index ee0b4e382..000000000 --- a/Tests/SKLoggingTests/LoggingTests.swift +++ /dev/null @@ -1,233 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -@_spi(Testing) import SKLogging -import SKTestSupport -import XCTest - -private func assertLogging( - logLevel: NonDarwinLogLevel = .default, - privacyLevel: NonDarwinLogPrivacy = .private, - expected: [String], - _ body: (NonDarwinLogger) -> Void, - file: StaticString = #filePath, - line: UInt = #line -) async { - // nonisolated(unsafe) because calls of `assertLogging` do not log to `logHandler` concurrently. - nonisolated(unsafe) var messages: [String] = [] - let logger = NonDarwinLogger( - subsystem: LoggingScope.subsystem, - category: "test", - logLevel: logLevel, - privacyLevel: privacyLevel, - overrideLogHandler: { messages.append($0) } - ) - body(logger) - await NonDarwinLogger.flush() - guard messages.count == expected.count else { - XCTFail( - """ - Number of messages does not match expected does not match expected - - Received: - \(messages.joined(separator: "\n")) - """, - file: file, - line: line - ) - return - } - for (message, expected) in zip(messages, expected) { - guard let firstNewline = message.firstIndex(of: "\n") else { - XCTFail( - """ - Did not find newline separating header from message in - \(message) - """, - file: file, - line: line - ) - continue - } - guard message.hasSuffix("\n---") else { - XCTFail("Message is expected to end with `---`", file: file, line: line) - return - } - let messageContent = String(message[message.index(after: firstNewline)...].dropLast(4)) - XCTAssertEqual(messageContent, expected, "Message does not match expected", file: file, line: line) - } - - messages.removeAll() -} - -final class LoggingTests: XCTestCase { - func testLoggingFormat() async throws { - let expectation = self.expectation(description: "message logged") - // nonisolated(unsafe) because we only have a single call to `logger.log` and that cannot race. - nonisolated(unsafe) var message: String = "" - let logger = NonDarwinLogger( - subsystem: LoggingScope.subsystem, - category: "test", - overrideLogHandler: { - message = $0 - expectation.fulfill() - } - ) - logger.log(level: .error, "my message") - try await fulfillmentOfOrThrow(expectation) - XCTAssert( - message.starts(with: "[org.swift.sourcekit-lsp:test] error"), - "Message did not have expected header. Received \n\(message)" - ) - XCTAssert(message.hasSuffix("\nmy message\n---"), "Message did not have expected body. Received \n\(message)") - } - - func testLoggingBasic() async { - await assertLogging( - expected: ["a"], - { - $0.log("a") - } - ) - - await assertLogging( - expected: [], - { _ in - } - ) - - await assertLogging(expected: ["b\n\nc"]) { - $0.log("b\n\nc") - } - } - - func testLogLevels() async { - await assertLogging( - logLevel: .default, - expected: ["d", "e", "f"] - ) { - $0.fault("d") - $0.error("e") - $0.log("f") - $0.info("g") - $0.debug("h") - } - - await assertLogging( - logLevel: .error, - expected: ["d", "e"] - ) { - $0.fault("d") - $0.error("e") - $0.log("f") - $0.info("g") - $0.debug("h") - } - - await assertLogging( - logLevel: .fault, - expected: ["d"] - ) { - $0.fault("d") - $0.error("e") - $0.log("f") - $0.info("g") - $0.debug("h") - } - } - - func testPrivacyMaskingLevels() async { - await assertLogging(expected: ["password is "]) { - let password: String = "1234" - $0.log("password is \(password, privacy: .sensitive)") - } - - await assertLogging(expected: ["username is root"]) { - let username: String = "root" - $0.log("username is \(username, privacy: .private)") - } - - await assertLogging(expected: ["username is root"]) { - let username: String = "root" - $0.log("username is \(username)") - } - - await assertLogging( - privacyLevel: .public, - expected: ["username is "] - ) { - let username: String = "root" - $0.log("username is \(username, privacy: .private)") - } - - await assertLogging( - privacyLevel: .public, - expected: ["username is "] - ) { - let username: String = "root" - $0.log("username is \(username)") - } - } - - func testPrivacyMaskingTypes() async { - await assertLogging( - privacyLevel: .public, - expected: ["logging a static string"] - ) { - $0.log("logging a \("static string")") - } - - await assertLogging( - privacyLevel: .public, - expected: ["logging from SKLoggingTests.LoggingTests"] - ) { - $0.log("logging from \(LoggingTests.self)") - } - - struct LogStringConvertible: CustomLogStringConvertible { - var description: String = "full description" - var redactedDescription: String = "redacted description" - } - - await assertLogging( - privacyLevel: .public, - expected: ["got redacted description"] - ) { - $0.log("got \(LogStringConvertible().forLogging)") - } - - await assertLogging( - privacyLevel: .private, - expected: ["got full description"] - ) { - $0.log("got \(LogStringConvertible().forLogging)") - } - } - - func testIntegerNotConsideredPrivate() async { - await assertLogging( - privacyLevel: .public, - expected: ["got 42"] - ) { - $0.log("got \(42)") - } - } - - func testBoolNotConsideredPrivate() async { - await assertLogging( - privacyLevel: .public, - expected: ["got true"] - ) { - $0.log("got \(true)") - } - } -} diff --git a/Tests/SKLoggingTests/PrettyPrintedRedactedJSONTests.swift b/Tests/SKLoggingTests/PrettyPrintedRedactedJSONTests.swift deleted file mode 100644 index 46d7b7e7a..000000000 --- a/Tests/SKLoggingTests/PrettyPrintedRedactedJSONTests.swift +++ /dev/null @@ -1,121 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import Foundation -@_spi(Testing) import SKLogging -import SKTestSupport -import XCTest - -class PrettyPrintedRedactedJSONTests: XCTestCase { - func testRecursiveRedactedDescription() { - struct Outer: Codable { - struct Inner: Codable { - var publicValue: Int - var redactedValue: String - } - var inner: Inner - } - - XCTAssertEqual( - Outer(inner: Outer.Inner(publicValue: 42, redactedValue: "password")).prettyPrintedRedactedJSON, - """ - { - "inner" : { - "publicValue" : 42, - "redactedValue" : "" - } - } - """ - ) - } - - func testOptionalInt() { - struct Struct: Codable { - var value: Int? - } - - XCTAssertEqual( - Struct(value: 42).prettyPrintedRedactedJSON, - """ - { - "value" : 42 - } - """ - ) - - XCTAssertEqual( - Struct(value: nil).prettyPrintedRedactedJSON, - """ - { - - } - """ - ) - } - - func testOptionalString() { - struct Struct: Codable { - var value: String? - } - - XCTAssertEqual( - Struct(value: "password").prettyPrintedRedactedJSON, - """ - { - "value" : "" - } - """ - ) - - XCTAssertEqual( - Struct(value: nil).prettyPrintedRedactedJSON, - """ - { - - } - """ - ) - } - - func testDouble() { - struct Struct: Codable { - var value: Double - } - - XCTAssertEqual( - Struct(value: 4.5).prettyPrintedRedactedJSON, - """ - { - "value" : 4.5 - } - """ - ) - } - - func testArrayOfStrings() { - struct Struct: Codable { - var value: [String] - } - - XCTAssertEqual( - Struct(value: ["password", "admin"]).prettyPrintedRedactedJSON, - """ - { - "value" : [ - "", - "" - ] - } - """ - ) - } -} diff --git a/Tests/SKUtilitiesTests/LineTableTests.swift b/Tests/SKUtilitiesTests/LineTableTests.swift index 20b2aaffc..a141c35e4 100644 --- a/Tests/SKUtilitiesTests/LineTableTests.swift +++ b/Tests/SKUtilitiesTests/LineTableTests.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SKLogging import SKUtilities import SwiftExtensions import TSCBasic @@ -22,6 +23,10 @@ fileprivate extension LineTable { } final class LineTableTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func checkLines(_ string: String, _ expected: [String], file: StaticString = #filePath, line: UInt = #line) { let table = LineTable(string) XCTAssertEqual(table.lines.map(String.init), expected, file: file, line: line) diff --git a/Tests/SemanticIndexTests/TaskSchedulerTests.swift b/Tests/SemanticIndexTests/TaskSchedulerTests.swift index 7e978f065..3530ea602 100644 --- a/Tests/SemanticIndexTests/TaskSchedulerTests.swift +++ b/Tests/SemanticIndexTests/TaskSchedulerTests.swift @@ -10,13 +10,18 @@ // //===----------------------------------------------------------------------===// -import SKLogging +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SemanticIndex import SwiftExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest final class TaskSchedulerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testHighPriorityTasksGetExecutedBeforeLowPriorityTasks() async throws { let highPriorityTasks: Int = 4 let lowPriorityTasks: Int = 2 diff --git a/Tests/SourceKitDTests/SourceKitDRegistryTests.swift b/Tests/SourceKitDTests/SourceKitDRegistryTests.swift index 16e18ff08..024940965 100644 --- a/Tests/SourceKitDTests/SourceKitDRegistryTests.swift +++ b/Tests/SourceKitDTests/SourceKitDRegistryTests.swift @@ -11,11 +11,12 @@ //===----------------------------------------------------------------------===// import Csourcekitd -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions import SKTestSupport import SourceKitD import SwiftExtensions import TSCBasic +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest final class SourceKitDRegistryTests: XCTestCase { diff --git a/Tests/SourceKitDTests/SourceKitDTests.swift b/Tests/SourceKitDTests/SourceKitDTests.swift index 137a50101..c3c8ee298 100644 --- a/Tests/SourceKitDTests/SourceKitDTests.swift +++ b/Tests/SourceKitDTests/SourceKitDTests.swift @@ -12,8 +12,9 @@ import Csourcekitd import Foundation -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +import SKLogging import SKTestSupport import SourceKitD import SwiftExtensions @@ -24,6 +25,10 @@ import XCTest import class TSCBasic.Process final class SourceKitDTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testMultipleNotificationHandlers() async throws { let sourcekitdPath = await ToolchainRegistry.forTesting.default!.sourcekitd! let sourcekitd = try await SourceKitD.getOrCreate( diff --git a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift index 465f66dac..89a87f118 100644 --- a/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift +++ b/Tests/SourceKitLSPTests/BackgroundIndexingTests.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SemanticIndex @@ -22,11 +22,16 @@ import SourceKitLSP import SwiftExtensions import TSCExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest import class TSCBasic.Process final class BackgroundIndexingTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testBackgroundIndexingOfSingleFile() async throws { let project = try await SwiftPMTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/BuildServerTests.swift b/Tests/SourceKitLSPTests/BuildServerTests.swift index 17ba30aa2..c75818f9d 100644 --- a/Tests/SourceKitLSPTests/BuildServerTests.swift +++ b/Tests/SourceKitLSPTests/BuildServerTests.swift @@ -11,9 +11,10 @@ //===----------------------------------------------------------------------===// @_spi(Testing) import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +import SKLogging import SKOptions import SKTestSupport @_spi(Testing) import SemanticIndex @@ -49,6 +50,10 @@ fileprivate actor TestBuildServer: CustomBuildServer { } final class BuildServerTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testClangdDocumentUpdatedBuildSettings() async throws { let project = try await CustomBuildServerTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/CallHierarchyTests.swift b/Tests/SourceKitLSPTests/CallHierarchyTests.swift index 502bb08e8..187ec45df 100644 --- a/Tests/SourceKitLSPTests/CallHierarchyTests.swift +++ b/Tests/SourceKitLSPTests/CallHierarchyTests.swift @@ -10,13 +10,18 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SwiftExtensions import TSCBasic import XCTest final class CallHierarchyTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testCallHierarchy() async throws { let project = try await IndexedSingleSwiftFileTestProject( """ diff --git a/Tests/SourceKitLSPTests/ClangdTests.swift b/Tests/SourceKitLSPTests/ClangdTests.swift index 2f0f6d7e9..59346b018 100644 --- a/Tests/SourceKitLSPTests/ClangdTests.swift +++ b/Tests/SourceKitLSPTests/ClangdTests.swift @@ -10,16 +10,21 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SourceKitLSP import SwiftExtensions import TSCBasic +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest final class ClangdTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testClangdGoToInclude() async throws { let project = try await MultiFileTestProject(files: [ "Object.h": "", diff --git a/Tests/SourceKitLSPTests/ClosureCompletionFormatTests.swift b/Tests/SourceKitLSPTests/ClosureCompletionFormatTests.swift index 59516b760..9a51ddcd8 100644 --- a/Tests/SourceKitLSPTests/ClosureCompletionFormatTests.swift +++ b/Tests/SourceKitLSPTests/ClosureCompletionFormatTests.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SKLogging import SourceKitLSP import Swift import SwiftBasicFormat @@ -46,6 +47,10 @@ private func assertFormatted( } final class ClosureCompletionFormatTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testSingleStatementClosureArg() { assertFormatted( source: """ diff --git a/Tests/SourceKitLSPTests/CodeActionTests.swift b/Tests/SourceKitLSPTests/CodeActionTests.swift index f282ad89a..13cb5a24f 100644 --- a/Tests/SourceKitLSPTests/CodeActionTests.swift +++ b/Tests/SourceKitLSPTests/CodeActionTests.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions @@ -33,6 +34,10 @@ private let clientCapabilitiesWithCodeActionSupport: ClientCapabilities = { }() final class CodeActionTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testCodeActionResponseLegacySupport() throws { let command = Command(title: "Title", command: "Command", arguments: [1, "text", 2.2, nil]) let codeAction = CodeAction(title: "1") diff --git a/Tests/SourceKitLSPTests/CodeLensTests.swift b/Tests/SourceKitLSPTests/CodeLensTests.swift index a190be32d..1432d38fa 100644 --- a/Tests/SourceKitLSPTests/CodeLensTests.swift +++ b/Tests/SourceKitLSPTests/CodeLensTests.swift @@ -10,11 +10,16 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest final class CodeLensTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testNoLenses() async throws { var codeLensCapabilities = TextDocumentClientCapabilities.CodeLens() codeLensCapabilities.supportedCommands = [ diff --git a/Tests/SourceKitLSPTests/CompilationDatabaseTests.swift b/Tests/SourceKitLSPTests/CompilationDatabaseTests.swift index c3c16290c..0ff940a28 100644 --- a/Tests/SourceKitLSPTests/CompilationDatabaseTests.swift +++ b/Tests/SourceKitLSPTests/CompilationDatabaseTests.swift @@ -11,7 +11,8 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SwiftExtensions import TSCBasic @@ -20,6 +21,10 @@ import ToolchainRegistry import XCTest final class CompilationDatabaseTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testModifyCompilationDatabase() async throws { let project = try await MultiFileTestProject(files: [ "main.cpp": """ diff --git a/Tests/SourceKitLSPTests/CrashRecoveryTests.swift b/Tests/SourceKitLSPTests/CrashRecoveryTests.swift index 0b9a5ad5c..e608b3476 100644 --- a/Tests/SourceKitLSPTests/CrashRecoveryTests.swift +++ b/Tests/SourceKitLSPTests/CrashRecoveryTests.swift @@ -10,9 +10,9 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SourceKitD @@ -43,6 +43,10 @@ fileprivate extension HoverResponse { } final class CrashRecoveryTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testSourcekitdCrashRecovery() async throws { try SkipUnless.platformIsDarwin("Linux and Windows use in-process sourcekitd") try SkipUnless.longTestsEnabled() diff --git a/Tests/SourceKitLSPTests/CrossLanguageRenameTests.swift b/Tests/SourceKitLSPTests/CrossLanguageRenameTests.swift index ff846c90b..18901b114 100644 --- a/Tests/SourceKitLSPTests/CrossLanguageRenameTests.swift +++ b/Tests/SourceKitLSPTests/CrossLanguageRenameTests.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest @@ -35,6 +36,10 @@ private let libAlibBCxxInteropPackageManifest = """ """ final class CrossLanguageRenameTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testZeroArgCFunction() async throws { try await assertMultiFileRename( files: [ diff --git a/Tests/SourceKitLSPTests/DefinitionTests.swift b/Tests/SourceKitLSPTests/DefinitionTests.swift index fd3ecfefe..0c339c37d 100644 --- a/Tests/SourceKitLSPTests/DefinitionTests.swift +++ b/Tests/SourceKitLSPTests/DefinitionTests.swift @@ -11,14 +11,18 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -@_spi(Testing) import SKLogging +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(Testing) @_spi(SourceKitLSP) import SKLogging import SKTestSupport import SwiftExtensions import XCTest class DefinitionTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testJumpToDefinitionAtEndOfIdentifier() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/DependencyTrackingTests.swift b/Tests/SourceKitLSPTests/DependencyTrackingTests.swift index f448d3c11..716bc8d1c 100644 --- a/Tests/SourceKitLSPTests/DependencyTrackingTests.swift +++ b/Tests/SourceKitLSPTests/DependencyTrackingTests.swift @@ -10,15 +10,19 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions import XCTest final class DependencyTrackingTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testDependenciesUpdatedSwift() async throws { let project = try await SwiftPMTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/DoccDocumentationTests.swift b/Tests/SourceKitLSPTests/DoccDocumentationTests.swift index b29a8c5d0..4c79d2df1 100644 --- a/Tests/SourceKitLSPTests/DoccDocumentationTests.swift +++ b/Tests/SourceKitLSPTests/DoccDocumentationTests.swift @@ -12,14 +12,18 @@ #if canImport(SwiftDocC) import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import SwiftDocC import XCTest final class DoccDocumentationTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testUnsupportedLanguage() async throws { try await renderDocumentation( markedText: "1️⃣", diff --git a/Tests/SourceKitLSPTests/DocumentColorTests.swift b/Tests/SourceKitLSPTests/DocumentColorTests.swift index 5fd50032d..34abcd2aa 100644 --- a/Tests/SourceKitLSPTests/DocumentColorTests.swift +++ b/Tests/SourceKitLSPTests/DocumentColorTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class DocumentColorTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Helpers private func performDocumentColorRequest(text: String) async throws -> [ColorInformation] { diff --git a/Tests/SourceKitLSPTests/DocumentSymbolTests.swift b/Tests/SourceKitLSPTests/DocumentSymbolTests.swift index 84621b979..a0084029a 100644 --- a/Tests/SourceKitLSPTests/DocumentSymbolTests.swift +++ b/Tests/SourceKitLSPTests/DocumentSymbolTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class DocumentSymbolTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Tests func testEmpty() async throws { diff --git a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift index 4a2188fa2..7798b946b 100644 --- a/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/DocumentTestDiscoveryTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class DocumentTestDiscoveryTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testIndexBasedDocumentTests() async throws { try SkipUnless.longTestsEnabled() diff --git a/Tests/SourceKitLSPTests/ExecuteCommandTests.swift b/Tests/SourceKitLSPTests/ExecuteCommandTests.swift index 4eaf60696..853e133e5 100644 --- a/Tests/SourceKitLSPTests/ExecuteCommandTests.swift +++ b/Tests/SourceKitLSPTests/ExecuteCommandTests.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKOptions import SKTestSupport @_spi(Testing) import SourceKitLSP @@ -19,6 +20,10 @@ import SwiftLanguageService import XCTest final class ExecuteCommandTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testLocationSemanticRefactoring() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/ExpandMacroTests.swift b/Tests/SourceKitLSPTests/ExpandMacroTests.swift index 42749ccec..38dab2f25 100644 --- a/Tests/SourceKitLSPTests/ExpandMacroTests.swift +++ b/Tests/SourceKitLSPTests/ExpandMacroTests.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport @_spi(Testing) import SourceKitLSP @@ -20,6 +20,10 @@ import SwiftLanguageService import XCTest final class ExpandMacroTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testFreestandingMacroExpansionWithoutGetReferenceDocumentWithoutPeekDocuments() async throws { try await testAttachedMacroExpansion(getReferenceDocument: false, peekDocuments: false) } diff --git a/Tests/SourceKitLSPTests/ExpectedIndexTaskTracker.swift b/Tests/SourceKitLSPTests/ExpectedIndexTaskTracker.swift index 2e2835341..b739f05bb 100644 --- a/Tests/SourceKitLSPTests/ExpectedIndexTaskTracker.swift +++ b/Tests/SourceKitLSPTests/ExpectedIndexTaskTracker.swift @@ -11,9 +11,9 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import BuildServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SemanticIndex import XCTest diff --git a/Tests/SourceKitLSPTests/FoldingRangeTests.swift b/Tests/SourceKitLSPTests/FoldingRangeTests.swift index ff89a85f8..bda7900c1 100644 --- a/Tests/SourceKitLSPTests/FoldingRangeTests.swift +++ b/Tests/SourceKitLSPTests/FoldingRangeTests.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest @@ -87,6 +88,10 @@ func assertFoldingRanges( } final class FoldingRangeTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testNoRanges() async throws { try await assertFoldingRanges(markedSource: "", expectedRanges: []) } diff --git a/Tests/SourceKitLSPTests/FormattingTests.swift b/Tests/SourceKitLSPTests/FormattingTests.swift index a9814e153..121d79cfc 100644 --- a/Tests/SourceKitLSPTests/FormattingTests.swift +++ b/Tests/SourceKitLSPTests/FormattingTests.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions @@ -21,6 +21,10 @@ import XCTest import class TSCBasic.Process final class FormattingTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testFormatting() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/HoverTests.swift b/Tests/SourceKitLSPTests/HoverTests.swift index 26e34aca9..220db1224 100644 --- a/Tests/SourceKitLSPTests/HoverTests.swift +++ b/Tests/SourceKitLSPTests/HoverTests.swift @@ -10,11 +10,16 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest final class HoverTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testBasic() async throws { try await assertHover( """ diff --git a/Tests/SourceKitLSPTests/ImplementationTests.swift b/Tests/SourceKitLSPTests/ImplementationTests.swift index 32eacb664..148549ed8 100644 --- a/Tests/SourceKitLSPTests/ImplementationTests.swift +++ b/Tests/SourceKitLSPTests/ImplementationTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import TSCBasic import XCTest final class ImplementationTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Utilities private func testImplementation( diff --git a/Tests/SourceKitLSPTests/IndexTests.swift b/Tests/SourceKitLSPTests/IndexTests.swift index 42d73fa24..b0490cb59 100644 --- a/Tests/SourceKitLSPTests/IndexTests.swift +++ b/Tests/SourceKitLSPTests/IndexTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SwiftExtensions import XCTest final class IndexTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testIndexSwiftModules() async throws { let project = try await SwiftPMTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/InlayHintTests.swift b/Tests/SourceKitLSPTests/InlayHintTests.swift index c3c8ae327..295ecf671 100644 --- a/Tests/SourceKitLSPTests/InlayHintTests.swift +++ b/Tests/SourceKitLSPTests/InlayHintTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class InlayHintTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Helpers func performInlayHintRequest( diff --git a/Tests/SourceKitLSPTests/LifecycleTests.swift b/Tests/SourceKitLSPTests/LifecycleTests.swift index 464bb37c7..7a8c030c4 100644 --- a/Tests/SourceKitLSPTests/LifecycleTests.swift +++ b/Tests/SourceKitLSPTests/LifecycleTests.swift @@ -10,14 +10,20 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +import SKLogging import SKOptions import SKTestSupport import XCTest /// Tests that test the overall state of the SourceKit-LSP server, that's not really specific to any language final class LifecycleTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testInitLocal() async throws { let testClient = try await TestSourceKitLSPClient(initialize: false) diff --git a/Tests/SourceKitLSPTests/LocalClangTests.swift b/Tests/SourceKitLSPTests/LocalClangTests.swift index 529d769c4..7aea9fa58 100644 --- a/Tests/SourceKitLSPTests/LocalClangTests.swift +++ b/Tests/SourceKitLSPTests/LocalClangTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport @_spi(Testing) import SourceKitLSP import XCTest final class LocalClangTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Tests func testSymbolInfo() async throws { diff --git a/Tests/SourceKitLSPTests/LocalSwiftTests.swift b/Tests/SourceKitLSPTests/LocalSwiftTests.swift index 56f3ecf61..837211046 100644 --- a/Tests/SourceKitLSPTests/LocalSwiftTests.swift +++ b/Tests/SourceKitLSPTests/LocalSwiftTests.swift @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SourceKitD @@ -23,6 +23,10 @@ import SwiftSyntax import XCTest final class LocalSwiftTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + private let quickFixCapabilities = ClientCapabilities( textDocument: TextDocumentClientCapabilities( codeAction: .init( diff --git a/Tests/SourceKitLSPTests/MainFilesProviderTests.swift b/Tests/SourceKitLSPTests/MainFilesProviderTests.swift index 55f61be56..88f41c808 100644 --- a/Tests/SourceKitLSPTests/MainFilesProviderTests.swift +++ b/Tests/SourceKitLSPTests/MainFilesProviderTests.swift @@ -10,15 +10,19 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions import XCTest final class MainFilesProviderTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testMainFileForHeaderInPackageTarget() async throws { let project = try await SwiftPMTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/OnTypeFormattingTests.swift b/Tests/SourceKitLSPTests/OnTypeFormattingTests.swift index 4c692735c..68d01d62c 100644 --- a/Tests/SourceKitLSPTests/OnTypeFormattingTests.swift +++ b/Tests/SourceKitLSPTests/OnTypeFormattingTests.swift @@ -10,13 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class OnTypeFormattingTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testOnlyFormatsSpecifiedLine() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/PublishDiagnosticsTests.swift b/Tests/SourceKitLSPTests/PublishDiagnosticsTests.swift index 0050ea7ca..9c6ec7f52 100644 --- a/Tests/SourceKitLSPTests/PublishDiagnosticsTests.swift +++ b/Tests/SourceKitLSPTests/PublishDiagnosticsTests.swift @@ -10,13 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import XCTest final class PublishDiagnosticsTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testUnknownIdentifierDiagnostic() async throws { let testClient = try await TestSourceKitLSPClient(usePullDiagnostics: false) let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift b/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift index ecabac28a..8ca9555b8 100644 --- a/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift +++ b/Tests/SourceKitLSPTests/PullDiagnosticsTests.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import LanguageServerProtocol -import LanguageServerProtocolExtensions -import LanguageServerProtocolJSONRPC -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocolExtensions +@_spi(SourceKitLSP) import LanguageServerProtocolTransport +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SemanticIndex import SourceKitLSP @@ -28,6 +28,10 @@ import Android #endif final class PullDiagnosticsTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testUnknownIdentifierDiagnostic() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/RangeFormattingTests.swift b/Tests/SourceKitLSPTests/RangeFormattingTests.swift index 53d271954..0c6dd9fc4 100644 --- a/Tests/SourceKitLSPTests/RangeFormattingTests.swift +++ b/Tests/SourceKitLSPTests/RangeFormattingTests.swift @@ -10,13 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SourceKitLSP import XCTest final class RangeFormattingTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testOnlyFormatsSpecifiedLines() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/ReferencesTests.swift b/Tests/SourceKitLSPTests/ReferencesTests.swift index b48d78b0e..bb95b9792 100644 --- a/Tests/SourceKitLSPTests/ReferencesTests.swift +++ b/Tests/SourceKitLSPTests/ReferencesTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest /// Tests that test the overall state of the SourceKit-LSP server, that's not really specific to any language final class ReferencesTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testReferencesInMacro() async throws { let project = try await IndexedSingleSwiftFileTestProject( """ diff --git a/Tests/SourceKitLSPTests/RenameAssertions.swift b/Tests/SourceKitLSPTests/RenameAssertions.swift index b93e547dd..5029b2ffa 100644 --- a/Tests/SourceKitLSPTests/RenameAssertions.swift +++ b/Tests/SourceKitLSPTests/RenameAssertions.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SKTestSupport import SKUtilities import XCTest diff --git a/Tests/SourceKitLSPTests/RenameTests.swift b/Tests/SourceKitLSPTests/RenameTests.swift index 9935389ac..a21404810 100644 --- a/Tests/SourceKitLSPTests/RenameTests.swift +++ b/Tests/SourceKitLSPTests/RenameTests.swift @@ -10,11 +10,16 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest final class RenameTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testRenameVariableBaseName() async throws { try await assertSingleFileRename( """ diff --git a/Tests/SourceKitLSPTests/RewriteSourceKitPlaceholdersTests.swift b/Tests/SourceKitLSPTests/RewriteSourceKitPlaceholdersTests.swift index 9d1efe685..83ece9303 100644 --- a/Tests/SourceKitLSPTests/RewriteSourceKitPlaceholdersTests.swift +++ b/Tests/SourceKitLSPTests/RewriteSourceKitPlaceholdersTests.swift @@ -10,12 +10,17 @@ // //===----------------------------------------------------------------------===// +import SKLogging import SKTestSupport import SourceKitLSP @_spi(Testing) import SwiftLanguageService import XCTest final class RewriteSourceKitPlaceholdersTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testClientDoesNotSupportSnippets() { let input = "foo(bar: <#T##Int##Int#>)" let rewritten = rewriteSourceKitPlaceholders(in: input, clientSupportsSnippets: false) diff --git a/Tests/SourceKitLSPTests/SemanticTokensTests.swift b/Tests/SourceKitLSPTests/SemanticTokensTests.swift index 38d88fed4..39b055d32 100644 --- a/Tests/SourceKitLSPTests/SemanticTokensTests.swift +++ b/Tests/SourceKitLSPTests/SemanticTokensTests.swift @@ -10,7 +10,8 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKOptions import SKTestSupport import SKUtilities @@ -22,6 +23,10 @@ import XCTest private typealias Token = SyntaxHighlightingToken final class SemanticTokensTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testIntArrayCoding() async throws { let tokens = SyntaxHighlightingTokens(tokens: [ Token( diff --git a/Tests/SourceKitLSPTests/SwiftCompileCommandsTest.swift b/Tests/SourceKitLSPTests/SwiftCompileCommandsTest.swift index a96366967..917bf5a51 100644 --- a/Tests/SourceKitLSPTests/SwiftCompileCommandsTest.swift +++ b/Tests/SourceKitLSPTests/SwiftCompileCommandsTest.swift @@ -11,12 +11,16 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SourceKitLSP import SwiftLanguageService import XCTest final class SwiftCompileCommandsTest: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } func testWorkingDirectoryIsAdded() { let settings = FileBuildSettings(compilerArguments: ["a", "b"], workingDirectory: "/build/root", language: .swift) diff --git a/Tests/SourceKitLSPTests/SwiftCompletionTests.swift b/Tests/SourceKitLSPTests/SwiftCompletionTests.swift index d90966d3b..1d4c87433 100644 --- a/Tests/SourceKitLSPTests/SwiftCompletionTests.swift +++ b/Tests/SourceKitLSPTests/SwiftCompletionTests.swift @@ -10,13 +10,18 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions import XCTest final class SwiftCompletionTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + // MARK: - Helpers private var snippetCapabilities = ClientCapabilities( diff --git a/Tests/SourceKitLSPTests/SwiftInterfaceTests.swift b/Tests/SourceKitLSPTests/SwiftInterfaceTests.swift index 808f9d2fd..752a263b2 100644 --- a/Tests/SourceKitLSPTests/SwiftInterfaceTests.swift +++ b/Tests/SourceKitLSPTests/SwiftInterfaceTests.swift @@ -11,8 +11,8 @@ //===----------------------------------------------------------------------===// import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKTestSupport import SKUtilities import SourceKitLSP @@ -20,6 +20,10 @@ import SwiftExtensions import XCTest final class SwiftInterfaceTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testSystemModuleInterface() async throws { let testClient = try await TestSourceKitLSPClient() let uri = DocumentURI(for: .swift) diff --git a/Tests/SourceKitLSPTests/SwiftPMIntegrationTests.swift b/Tests/SourceKitLSPTests/SwiftPMIntegrationTests.swift index 4e21739a4..8e1f576fb 100644 --- a/Tests/SourceKitLSPTests/SwiftPMIntegrationTests.swift +++ b/Tests/SourceKitLSPTests/SwiftPMIntegrationTests.swift @@ -12,13 +12,17 @@ import BuildServerIntegration import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions import XCTest final class SwiftPMIntegrationTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } func testSwiftPMIntegration() async throws { try await SkipUnless.sourcekitdSupportsPlugin() diff --git a/Tests/SourceKitLSPTests/SwiftSignatureHelpTests.swift b/Tests/SourceKitLSPTests/SwiftSignatureHelpTests.swift index bcfd40395..caad720a6 100644 --- a/Tests/SourceKitLSPTests/SwiftSignatureHelpTests.swift +++ b/Tests/SourceKitLSPTests/SwiftSignatureHelpTests.swift @@ -10,13 +10,18 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitLSP import SwiftExtensions import XCTest final class SwiftSignatureHelpTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testSignatureHelpFunction() async throws { try await SkipUnless.sourcekitdSupportsSignatureHelp() diff --git a/Tests/SourceKitLSPTests/SyntaxRefactorTests.swift b/Tests/SourceKitLSPTests/SyntaxRefactorTests.swift index 85273bfaf..ee424ce63 100644 --- a/Tests/SourceKitLSPTests/SyntaxRefactorTests.swift +++ b/Tests/SourceKitLSPTests/SyntaxRefactorTests.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SKLogging import SKTestSupport @_spi(Testing) import SourceKitLSP import SwiftLanguageService @@ -19,6 +20,10 @@ import SwiftSyntax import XCTest final class SyntaxRefactorTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testAddDocumentationRefactor() throws { try assertRefactor( """ diff --git a/Tests/SourceKitLSPTests/TypeHierarchyTests.swift b/Tests/SourceKitLSPTests/TypeHierarchyTests.swift index 8ceccd061..7fccf98a5 100644 --- a/Tests/SourceKitLSPTests/TypeHierarchyTests.swift +++ b/Tests/SourceKitLSPTests/TypeHierarchyTests.swift @@ -10,13 +10,18 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SwiftExtensions import TSCBasic import XCTest final class TypeHierarchyTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testRootClassSupertypes() async throws { let project = try await IndexedSingleSwiftFileTestProject( """ diff --git a/Tests/SourceKitLSPTests/WorkspaceSymbolsTests.swift b/Tests/SourceKitLSPTests/WorkspaceSymbolsTests.swift index 2b1929cdc..8d56aa634 100644 --- a/Tests/SourceKitLSPTests/WorkspaceSymbolsTests.swift +++ b/Tests/SourceKitLSPTests/WorkspaceSymbolsTests.swift @@ -10,11 +10,16 @@ // //===----------------------------------------------------------------------===// -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import XCTest class WorkspaceSymbolsTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testWorkspaceSymbolsAcrossPackages() async throws { let project = try await MultiFileTestProject( files: [ diff --git a/Tests/SourceKitLSPTests/WorkspaceTestDiscoveryTests.swift b/Tests/SourceKitLSPTests/WorkspaceTestDiscoveryTests.swift index bdc573cfd..1ab8e5c09 100644 --- a/Tests/SourceKitLSPTests/WorkspaceTestDiscoveryTests.swift +++ b/Tests/SourceKitLSPTests/WorkspaceTestDiscoveryTests.swift @@ -12,12 +12,14 @@ @_spi(Testing) import BuildServerIntegration import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SemanticIndex @_spi(Testing) import SourceKitLSP import SwiftExtensions import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest import struct TSCBasic.AbsolutePath @@ -30,6 +32,10 @@ private let packageManifestWithTestTarget = """ """ final class WorkspaceTestDiscoveryTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testIndexBasedWorkspaceXCTests() async throws { try SkipUnless.longTestsEnabled() diff --git a/Tests/SourceKitLSPTests/WorkspaceTests.swift b/Tests/SourceKitLSPTests/WorkspaceTests.swift index 1a813a5d5..0205a5361 100644 --- a/Tests/SourceKitLSPTests/WorkspaceTests.swift +++ b/Tests/SourceKitLSPTests/WorkspaceTests.swift @@ -11,10 +11,10 @@ //===----------------------------------------------------------------------===// import BuildServerIntegration -import BuildServerProtocol +@_spi(SourceKitLSP) import BuildServerProtocol import Foundation -import LanguageServerProtocol -import SKLogging +@_spi(SourceKitLSP) import LanguageServerProtocol +@_spi(SourceKitLSP) import SKLogging import SKOptions import SKTestSupport import SemanticIndex @@ -22,9 +22,13 @@ import SourceKitLSP import SwiftExtensions import TSCBasic import ToolchainRegistry +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest final class WorkspaceTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } func testMultipleSwiftPMWorkspaces() async throws { try await SkipUnless.sourcekitdSupportsPlugin() diff --git a/Tests/SwiftExtensionsTests/AsyncUtilsTests.swift b/Tests/SwiftExtensionsTests/AsyncUtilsTests.swift deleted file mode 100644 index 21f0f3779..000000000 --- a/Tests/SwiftExtensionsTests/AsyncUtilsTests.swift +++ /dev/null @@ -1,72 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// -//===----------------------------------------------------------------------===// - -import SKLogging -import SKTestSupport -import SwiftExtensions -import XCTest - -#if os(Windows) -import WinSDK -#elseif canImport(Android) -import Android -#endif - -final class AsyncUtilsTests: XCTestCase { - func testWithTimeout() async throws { - let expectation = self.expectation(description: "withTimeout body finished") - await assertThrowsError( - try await withTimeout(.seconds(0.1)) { - try? await Task.sleep(for: .seconds(10)) - XCTAssert(Task.isCancelled) - expectation.fulfill() - } - ) { error in - XCTAssert(error is TimeoutError, "Received unexpected error \(error)") - } - try await fulfillmentOfOrThrow(expectation) - } - - func testWithTimeoutReturnsImmediatelyEvenIfBodyDoesntCooperateInCancellation() async throws { - let start = Date() - await assertThrowsError( - try await withTimeout(.seconds(0.1)) { - #if os(Windows) - Sleep(10_000 /*ms*/) - #else - sleep(10 /*s*/) - #endif - } - ) { error in - XCTAssert(error is TimeoutError, "Received unexpected error \(error)") - } - XCTAssert(Date().timeIntervalSince(start) < 5) - } - - func testWithTimeoutEscalatesPriority() async throws { - let expectation = self.expectation(description: "Timeout started") - let task = Task(priority: .background) { - // We don't actually hit the timeout. It's just a large value. - try await withTimeout(.seconds(defaultTimeout * 2)) { - expectation.fulfill() - try await repeatUntilExpectedResult(sleepInterval: .seconds(0.1)) { - logger.debug("Current priority: \(Task.currentPriority.rawValue)") - return Task.currentPriority > .background - } - } - } - try await fulfillmentOfOrThrow(expectation) - try await Task(priority: .high) { - try await task.value - }.value - } -} diff --git a/Tests/SwiftSourceKitPluginTests/PluginSwiftPMTestProject.swift b/Tests/SwiftSourceKitPluginTests/PluginSwiftPMTestProject.swift index a636d567f..771e24d7e 100644 --- a/Tests/SwiftSourceKitPluginTests/PluginSwiftPMTestProject.swift +++ b/Tests/SwiftSourceKitPluginTests/PluginSwiftPMTestProject.swift @@ -12,7 +12,7 @@ import BuildServerIntegration import Foundation -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol import SKTestSupport import ToolchainRegistry diff --git a/Tests/SwiftSourceKitPluginTests/SwiftSourceKitPluginTests.swift b/Tests/SwiftSourceKitPluginTests/SwiftSourceKitPluginTests.swift index e6cc361dd..c38134008 100644 --- a/Tests/SwiftSourceKitPluginTests/SwiftSourceKitPluginTests.swift +++ b/Tests/SwiftSourceKitPluginTests/SwiftSourceKitPluginTests.swift @@ -12,7 +12,8 @@ import CompletionScoring import Csourcekitd -import LanguageServerProtocol +@_spi(SourceKitLSP) import LanguageServerProtocol +import SKLogging import SKTestSupport import SourceKitD import SwiftExtensions @@ -44,6 +45,10 @@ final class SwiftSourceKitPluginTests: XCTestCase { ) } + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testBasicCompletion() async throws { try await SkipUnless.sourcekitdSupportsPlugin() try await SkipUnless.sourcekitdSupportsFullDocumentationInCompletion() diff --git a/Tests/TSCExtensionsTests/ProcessRunTests.swift b/Tests/TSCExtensionsTests/ProcessRunTests.swift index 48ffe622a..61d5b8fe1 100644 --- a/Tests/TSCExtensionsTests/ProcessRunTests.swift +++ b/Tests/TSCExtensionsTests/ProcessRunTests.swift @@ -13,6 +13,7 @@ import SKTestSupport import SwiftExtensions import TSCExtensions +@_spi(SourceKitLSP) import ToolsProtocolsSwiftExtensions import XCTest import struct TSCBasic.AbsolutePath diff --git a/Tests/ToolchainRegistryTests/ToolchainRegistryTests.swift b/Tests/ToolchainRegistryTests/ToolchainRegistryTests.swift index 32d9b452a..49f5db515 100644 --- a/Tests/ToolchainRegistryTests/ToolchainRegistryTests.swift +++ b/Tests/ToolchainRegistryTests/ToolchainRegistryTests.swift @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +import SKLogging import SKTestSupport import SKUtilities import SwiftExtensions @@ -22,6 +23,10 @@ import Android #endif final class ToolchainRegistryTests: XCTestCase { + override func setUp() async throws { + LoggingScope.configureDefaultLoggingSubsystem("org.swift.sourcekit-lsp-tests") + } + func testDefaultSingleToolchain() async throws { let tr = ToolchainRegistry(toolchains: [ Toolchain(identifier: "a", displayName: "a", path: URL(fileURLWithPath: "/dummy"))