From 3a9544ea164917323ce5732b13af47c53b04f53a Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 12 Oct 2022 18:15:57 +0200 Subject: [PATCH 01/28] Add badge for DocC documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51a8de3..cc4835e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SwiftLSP -[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fcodeface-io%2FSwiftLSP%2Fbadge%3Ftype%3Dswift-versions&style=flat-square)](https://swiftpackageindex.com/codeface-io/SwiftLSP) [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fcodeface-io%2FSwiftLSP%2Fbadge%3Ftype%3Dplatforms&style=flat-square)](https://swiftpackageindex.com/codeface-io/SwiftLSP) [![](https://img.shields.io/badge/License-MIT-lightgrey.svg?style=flat-square)](LICENSE) +[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fcodeface-io%2FSwiftLSP%2Fbadge%3Ftype%3Dswift-versions&style=flat-square)](https://swiftpackageindex.com/codeface-io/SwiftLSP)  [![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fcodeface-io%2FSwiftLSP%2Fbadge%3Ftype%3Dplatforms&style=flat-square)](https://swiftpackageindex.com/codeface-io/SwiftLSP)  [![](https://img.shields.io/badge/Documentation-DocC-blue.svg?style=flat-square)](https://swiftpackageindex.com/codeface-io/SwiftLSP/documentation)  [![](https://img.shields.io/badge/License-MIT-lightgrey.svg?style=flat-square)](LICENSE) 👩🏻‍🚀 *This project [is still a tad experimental](#development-status). Contributors and pioneers welcome!* From 3c6bb6c9ea85cc1f6683d05cc8d596cc16cfb8fa Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 16 Nov 2022 15:59:21 +0100 Subject: [PATCH 02/28] Add convenience for creating sourcekit-lsp executable configuration --- Sources/Server Communication/LSP.ServerExecutable.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/Server Communication/LSP.ServerExecutable.swift b/Sources/Server Communication/LSP.ServerExecutable.swift index 062deda..63f420e 100644 --- a/Sources/Server Communication/LSP.ServerExecutable.swift +++ b/Sources/Server Communication/LSP.ServerExecutable.swift @@ -32,4 +32,12 @@ public extension LSP { } } +public extension Executable.Configuration +{ + static var sourceKitLSP: Executable.Configuration + { + .init(path: "/usr/bin/xcrun", arguments: ["sourcekit-lsp"]) + } +} + #endif From a3e6b929cdf76aa4603e9afe778165ef79afc7e8 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 16 Nov 2022 16:14:43 +0100 Subject: [PATCH 03/28] Add srckit-lsp environment variable just to remember it's an option --- Sources/Server Communication/LSP.ServerExecutable.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Server Communication/LSP.ServerExecutable.swift b/Sources/Server Communication/LSP.ServerExecutable.swift index 63f420e..1403973 100644 --- a/Sources/Server Communication/LSP.ServerExecutable.swift +++ b/Sources/Server Communication/LSP.ServerExecutable.swift @@ -36,7 +36,9 @@ public extension Executable.Configuration { static var sourceKitLSP: Executable.Configuration { - .init(path: "/usr/bin/xcrun", arguments: ["sourcekit-lsp"]) + .init(path: "/usr/bin/xcrun", + arguments: ["sourcekit-lsp"], + environment: ["SOURCEKIT_LOGGING": "0"]) } } From daf0187bfa006d94f08997aef1b9edf7aed80b48 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Tue, 22 Nov 2022 19:56:05 +0100 Subject: [PATCH 04/28] Add convenience for passing the LSP client's own process ID to the LSP server --- .../Server Life Cycle/LSP.Message.Request+Initialize.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Use Cases/Server Life Cycle/LSP.Message.Request+Initialize.swift b/Sources/Use Cases/Server Life Cycle/LSP.Message.Request+Initialize.swift index 69727c8..33cf81f 100644 --- a/Sources/Use Cases/Server Life Cycle/LSP.Message.Request+Initialize.swift +++ b/Sources/Use Cases/Server Life Cycle/LSP.Message.Request+Initialize.swift @@ -6,9 +6,11 @@ public extension LSP.Message.Request { /** https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initialize + + - Parameter clientProcessID: [We assume](https://github.com/ChimeHQ/ProcessService/pull/3) this is the process ID of the actual LSP **client**, which is not necessarily the same process as the server's parent process that technically launched the LSP server. This is important because the LSP client might interact with the LSP server via intermediate processes like [LSPService](https://github.com/codeface-io/LSPService) or XPC services. You may omit this parameter and SwiftLSP will use the current process's ID. This will virtually always be correct since the LSP client typically creates the initialize request. */ static func initialize(folder: URL, - clientProcessID: Int, + clientProcessID: Int = Int(ProcessInfo.processInfo.processIdentifier), capabilities: JSON = defaultClientCapabilities) -> Self { .init(method: "initialize", From 5c7425c31e6fef785907dcff5057421aa54fd2e9 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 23 Nov 2022 11:42:18 +0100 Subject: [PATCH 05/28] Update dependencies --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 4a2ef89..6975f2a 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.1.1" + exact: "0.1.3" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.1.1" + exact: "0.2.0" ) ], targets: [ From 063cb6398928d789a55375bc814e918cfbf2a086 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 21 Dec 2022 15:49:39 +0100 Subject: [PATCH 06/28] Add TODO --- .../Server Communication/LSP.ServerCommunicationHandler.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift index 390ec5f..26b9c4b 100644 --- a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift +++ b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift @@ -23,6 +23,7 @@ extension LSP.ServerCommunicationHandler extension LSP { + // TODO: should this be named client??? ... the client sends request via its server connection to the server ... public typealias Server = ServerCommunicationHandler /// An actor for easy communication with an LSP server via an ``LSPServerConnection`` From 9c2c8fb4f10801093bdefb50e129d736fc52eac1 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sat, 24 Dec 2022 13:23:04 +0100 Subject: [PATCH 07/28] Make value types Sendable --- Sources/Message/LSP.Message.swift | 12 ++++++------ Sources/Packet/LSP.Packet.swift | 2 +- .../LSP.LanguageIdentifier.swift | 2 +- Sources/Use Cases/Basic LSP Types/LSPLocation.swift | 6 +++--- .../LSPTextDocumentPositionParams.swift | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Sources/Message/LSP.Message.swift b/Sources/Message/LSP.Message.swift index 685781f..92d2d31 100644 --- a/Sources/Message/LSP.Message.swift +++ b/Sources/Message/LSP.Message.swift @@ -13,7 +13,7 @@ extension LSP See */ - public enum Message: Equatable + public enum Message: Equatable, Sendable { case response(Response) case request(Request) @@ -26,7 +26,7 @@ extension LSP See */ - public struct Response: Equatable + public struct Response: Equatable, Sendable { public init(id: NullableID, result: Result) { @@ -50,7 +50,7 @@ extension LSP } /// An LSP message ID that can also be null - public enum NullableID: Equatable + public enum NullableID: Equatable, Sendable { case value(ID), null } @@ -60,7 +60,7 @@ extension LSP See */ - public struct Request: Equatable + public struct Request: Equatable, Sendable { public init(id: ID = ID(), method: String, params: JSON.Container?) { @@ -75,7 +75,7 @@ extension LSP } /// A basic LSP message ID is either a string or an integer - public enum ID: Hashable + public enum ID: Hashable, Sendable { public init() { self = .string(UUID().uuidString) } @@ -87,7 +87,7 @@ extension LSP See */ - public struct Notification: Equatable + public struct Notification: Equatable, Sendable { public init(method: String, params: JSON.Container?) { diff --git a/Sources/Packet/LSP.Packet.swift b/Sources/Packet/LSP.Packet.swift index 7dbedc7..f1fd0ec 100644 --- a/Sources/Packet/LSP.Packet.swift +++ b/Sources/Packet/LSP.Packet.swift @@ -8,7 +8,7 @@ public extension LSP See how [the LSP specifies its "Base Protocol"](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#baseProtocol). */ - struct Packet: Equatable + struct Packet: Equatable, Sendable { /** Detects a ``LSP/Packet`` that starts at the beginning of a `Data` instance diff --git a/Sources/Server Communication/LSP.LanguageIdentifier.swift b/Sources/Server Communication/LSP.LanguageIdentifier.swift index d03e852..8f7a73a 100644 --- a/Sources/Server Communication/LSP.LanguageIdentifier.swift +++ b/Sources/Server Communication/LSP.LanguageIdentifier.swift @@ -5,7 +5,7 @@ public extension LSP See [the corresponding specification](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem) */ - struct LanguageIdentifier + struct LanguageIdentifier: Sendable { /** Create an LSP-conform language identifier from a language name diff --git a/Sources/Use Cases/Basic LSP Types/LSPLocation.swift b/Sources/Use Cases/Basic LSP Types/LSPLocation.swift index e88e602..143bff2 100644 --- a/Sources/Use Cases/Basic LSP Types/LSPLocation.swift +++ b/Sources/Use Cases/Basic LSP Types/LSPLocation.swift @@ -1,7 +1,7 @@ /** https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#location */ -public struct LSPLocation: Codable, Equatable +public struct LSPLocation: Codable, Equatable, Sendable { public let uri: LSPDocumentUri public let range: LSPRange @@ -33,7 +33,7 @@ public extension LSPRange } } -public struct LSPRange: Codable, Equatable +public struct LSPRange: Codable, Equatable, Sendable { /** * The range's start position. @@ -46,7 +46,7 @@ public struct LSPRange: Codable, Equatable public let end: LSPPosition } -public struct LSPPosition: Codable, Equatable +public struct LSPPosition: Codable, Equatable, Sendable { /** * Line position in a document (zero-based). diff --git a/Sources/Use Cases/Basic LSP Types/LSPTextDocumentPositionParams.swift b/Sources/Use Cases/Basic LSP Types/LSPTextDocumentPositionParams.swift index ebb4b39..7781344 100644 --- a/Sources/Use Cases/Basic LSP Types/LSPTextDocumentPositionParams.swift +++ b/Sources/Use Cases/Basic LSP Types/LSPTextDocumentPositionParams.swift @@ -1,7 +1,7 @@ /** https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentPositionParams */ -public struct LSPTextDocumentPositionParams: Codable +public struct LSPTextDocumentPositionParams: Codable, Sendable { /** * The text document. @@ -14,7 +14,7 @@ public struct LSPTextDocumentPositionParams: Codable public let position: LSPPosition } -public struct LSPTextDocumentIdentifier: Codable +public struct LSPTextDocumentIdentifier: Codable, Sendable { /** * The text document's URI. From 46ba14e11ad4e91ebceedcd636a17bc60457acbf Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Thu, 5 Jan 2023 16:24:08 +0100 Subject: [PATCH 08/28] Make LSPDocumentSymbol sendable --- Sources/Use Cases/Symbols/LSPDocumentSymbol.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift index 4f5c520..9026e2a 100644 --- a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift +++ b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift @@ -39,13 +39,13 @@ public extension LSPDocumentSymbol.SymbolKind /** https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentSymbol */ -public struct LSPDocumentSymbol: Codable, Equatable +public struct LSPDocumentSymbol: Codable, Equatable, Sendable { public let name: String public var decodedKind: SymbolKind? { .init(rawValue: kind) } - public enum SymbolKind: Int, CaseIterable, Codable, Equatable + public enum SymbolKind: Int, CaseIterable, Codable, Equatable, Sendable { case File = 1 case Module = 2 From 9cb99d55860c9e50fb235714273a7c405a8d015a Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Thu, 5 Jan 2023 16:26:30 +0100 Subject: [PATCH 09/28] Fix my stupid concurrency mistake (bug) --- .../LSP.ServerCommunicationHandler.swift | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift index 26b9c4b..652a7f0 100644 --- a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift +++ b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift @@ -117,20 +117,20 @@ extension LSP Task { - [weak self] in await self?.save(continuation, for: request.id) + await self.save(continuation, for: request.id) + + do + { + try await connection.sendToServer(.request(request)) + } + catch + { + await removeContinuation(for: request.id) + continuation.resume(throwing: error) + } } } - do - { - try await connection.sendToServer(.request(request)) - } - catch - { - removeContinuation(for: request.id) - throw error - } - return try await json } From db29f1614469e390d95ca82f181cf4517159ee33 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Thu, 5 Jan 2023 18:38:49 +0100 Subject: [PATCH 10/28] Simplify async request function --- .../LSP.ServerCommunicationHandler.swift | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift index 652a7f0..8a0f061 100644 --- a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift +++ b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift @@ -111,13 +111,13 @@ extension LSP */ public func request(_ request: Request) async throws -> JSON { - async let json: JSON = withCheckedThrowingContinuation + try await withCheckedThrowingContinuation { continuation in Task { - await self.save(continuation, for: request.id) + save(continuation, for: request.id) do { @@ -125,13 +125,11 @@ extension LSP } catch { - await removeContinuation(for: request.id) + removeContinuation(for: request.id) continuation.resume(throwing: error) } } } - - return try await json } private func serverDidSend(_ response: Response) async From fad5d124a862e38aa071f8ed1aac275a6c579fb6 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Thu, 5 Jan 2023 19:15:29 +0100 Subject: [PATCH 11/28] Update dependencies --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 6975f2a..75fc999 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.1.3" + exact: "0.1.6" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.2.0" + exact: "0.2.2" ) ], targets: [ From cad6ae9a76bb671f7fd3f123af179bfcb4bbd8fc Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 22 Jan 2023 10:14:42 +0100 Subject: [PATCH 12/28] Bump dependency versions --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 75fc999..e0c2b8d 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.1.6" + exact: "0.1.7" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.2.2" + exact: "0.3.0" ) ], targets: [ From a30debb8357d21130f1a58d5cf3efa6e3692924b Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 25 Jan 2023 14:16:38 +0100 Subject: [PATCH 13/28] Move LSP.CodebaseLocation from LSPServiceKit to here --- Sources/LSP.CodebaseLocation.swift | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Sources/LSP.CodebaseLocation.swift diff --git a/Sources/LSP.CodebaseLocation.swift b/Sources/LSP.CodebaseLocation.swift new file mode 100644 index 0000000..eaab953 --- /dev/null +++ b/Sources/LSP.CodebaseLocation.swift @@ -0,0 +1,22 @@ +import Foundation + +public extension LSP { + + /** + Demarcates a codebase in the file system: by location, language and source file types + */ + struct CodebaseLocation: Codable, Equatable, Sendable { + + public init(folder: URL, + languageName: String, + codeFileEndings: [String]) { + self.folder = folder + self.languageName = languageName + self.codeFileEndings = codeFileEndings + } + + public var folder: URL + public let languageName: String + public let codeFileEndings: [String] + } +} From 863f0c3cf8a8797c0a4df8f6b09ae776ae8527c1 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 19 Feb 2023 10:00:28 +0100 Subject: [PATCH 14/28] Make some initializers public, so clients can use the types in unit test --- Sources/Use Cases/Basic LSP Types/LSPLocation.swift | 12 ++++++++++++ Sources/Use Cases/Symbols/LSPDocumentSymbol.swift | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/Sources/Use Cases/Basic LSP Types/LSPLocation.swift b/Sources/Use Cases/Basic LSP Types/LSPLocation.swift index 143bff2..ca54864 100644 --- a/Sources/Use Cases/Basic LSP Types/LSPLocation.swift +++ b/Sources/Use Cases/Basic LSP Types/LSPLocation.swift @@ -35,6 +35,12 @@ public extension LSPRange public struct LSPRange: Codable, Equatable, Sendable { + public init(start: LSPPosition, end: LSPPosition) + { + self.start = start + self.end = end + } + /** * The range's start position. */ @@ -48,6 +54,12 @@ public struct LSPRange: Codable, Equatable, Sendable public struct LSPPosition: Codable, Equatable, Sendable { + public init(line: Int, character: Int) + { + self.line = line + self.character = character + } + /** * Line position in a document (zero-based). */ diff --git a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift index 9026e2a..d2fe397 100644 --- a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift +++ b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift @@ -41,6 +41,19 @@ public extension LSPDocumentSymbol.SymbolKind */ public struct LSPDocumentSymbol: Codable, Equatable, Sendable { + public init(name: String, + kind: Int, + range: LSPRange, + selectionRange: LSPRange, + children: [LSPDocumentSymbol] = []) + { + self.name = name + self.kind = kind + self.range = range + self.selectionRange = selectionRange + self.children = children + } + public let name: String public var decodedKind: SymbolKind? { .init(rawValue: kind) } From aa9b169b9a34ba342c38a03b7c33bc029c3764fd Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 5 Mar 2023 14:16:08 +0100 Subject: [PATCH 15/28] Bump dependency versions --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index e0c2b8d..4158545 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.1.7" + exact: "0.2.0" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.3.0" + exact: "0.4.0" ) ], targets: [ From dc02f949eba2bad6f6f0240d65cb8e4191615081 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Tue, 28 Mar 2023 19:20:00 +0200 Subject: [PATCH 16/28] Bump dependency versions --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 4158545..2f12ed3 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.2.0" + exact: "0.3.0" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.4.0" + exact: "0.5.0" ) ], targets: [ From f6f5837b3d3f17e452a873390783127811b0a6ca Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Fri, 31 Mar 2023 13:45:59 +0200 Subject: [PATCH 17/28] Update dependencies --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 2f12ed3..3e15898 100644 --- a/Package.swift +++ b/Package.swift @@ -13,11 +13,11 @@ let package = Package( dependencies: [ .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.3.0" + exact: "0.3.1" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", - exact: "0.5.0" + exact: "0.5.1" ) ], targets: [ From 25be8330cdbd9251900462ef05cda273b61d4ecf Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Fri, 9 Jun 2023 09:41:49 +0200 Subject: [PATCH 18/28] Make symbol children optional to adhere to LSP --- Sources/Use Cases/Symbols/LSPDocumentSymbol.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift index d2fe397..43aac41 100644 --- a/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift +++ b/Sources/Use Cases/Symbols/LSPDocumentSymbol.swift @@ -94,5 +94,5 @@ public struct LSPDocumentSymbol: Codable, Equatable, Sendable public let selectionRange: LSPRange - public let children: [Self] + public let children: [Self]? } From be1d54972d02511ccebcadba59881b8c9ad5c636 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Fri, 9 Jun 2023 19:39:18 +0200 Subject: [PATCH 19/28] Enable optional results, considering NSNull cannot be decoded --- .../LSP.ServerCommunicationHandler.swift | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift index 8a0f061..8d13e82 100644 --- a/Sources/Server Communication/LSP.ServerCommunicationHandler.swift +++ b/Sources/Server Communication/LSP.ServerCommunicationHandler.swift @@ -17,7 +17,22 @@ extension LSP.ServerCommunicationHandler */ public func request(_ request: LSP.Request) async throws -> Value { - try await self.request(request).decode() + let resultJSON = try await self.request(request) + + guard resultJSON != .null else + { + throw "Cannot interpret JSON as \(Value.self). If \(Value.self) is an optional type, you must use function requestOptional(...) instead of request(...)" + } + + return try resultJSON.decode() + } + + // TODO: can we rather "overload" the plain `request(...)` func properly so it covers the optional and non-optional code without ambiguity? + public func requestOptional(_ request: LSP.Request) async throws -> Value? + { + let resultJSON = try await self.request(request) + guard resultJSON != .null else { return nil } + return try resultJSON.decode() } } @@ -146,7 +161,13 @@ extension LSP switch response.result { case .success(let jsonResult): + if jsonResult == .null + { + log(verbose: "Received valid LSP response message with result property of ") + } + continuation.resume(returning: jsonResult) + case .failure(let errorResult): // TODO: ensure clients actually try to cast thrown errors to LSP.ErrorResult continuation.resume(throwing: errorResult) From bf0307663f75061b26121a19cbe2db6f22c826a9 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Fri, 9 Jun 2023 19:39:46 +0200 Subject: [PATCH 20/28] Properly type symbol request result as optional --- .../Symbols/LSP.ServerCommunicationHandler+Symbols.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Use Cases/Symbols/LSP.ServerCommunicationHandler+Symbols.swift b/Sources/Use Cases/Symbols/LSP.ServerCommunicationHandler+Symbols.swift index 4e765b4..d10809d 100644 --- a/Sources/Use Cases/Symbols/LSP.ServerCommunicationHandler+Symbols.swift +++ b/Sources/Use Cases/Symbols/LSP.ServerCommunicationHandler+Symbols.swift @@ -1,8 +1,8 @@ extension LSP.ServerCommunicationHandler { /// This just adds the knowledge of what result type the server returns - public func requestSymbols(in document: LSPDocumentUri) async throws -> [LSPDocumentSymbol] + public func requestSymbols(in document: LSPDocumentUri) async throws -> [LSPDocumentSymbol]? { - try await request(.symbols(in: document)) + try await requestOptional(.symbols(in: document)) } } From f230348a4d573f76c9bce87d0d3e2621e5ee98d7 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 28 Jun 2023 16:51:48 +0200 Subject: [PATCH 21/28] Add helper for logging log message notifications --- .../Message/LSP.Notification+LogMessage.swift | 41 +++++++++++++++++++ Sources/Packet/LSP.Packet.swift | 2 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 Sources/Message/LSP.Notification+LogMessage.swift diff --git a/Sources/Message/LSP.Notification+LogMessage.swift b/Sources/Message/LSP.Notification+LogMessage.swift new file mode 100644 index 0000000..0afb565 --- /dev/null +++ b/Sources/Message/LSP.Notification+LogMessage.swift @@ -0,0 +1,41 @@ +import SwiftyToolz + +public extension LSP.Notification { + + var logMessageParameters: LSP.LogMessageParams? { + method == "window/logMessage" ? try? params?.json().decode() : nil + } +} + +public extension LSP.LogMessageParams { + + var logLevel: Log.Level { + switch type { + case 1: return .error + case 2: return .warning + case 3: return .info + case 4: return .verbose + default: + log(error: "Unknown \(Self.self) message type code: \(type). See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#messageType") + return .info + } + } +} + +public extension LSP { + + /// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#logMessageParams + struct LogMessageParams: Codable { + /** + The message type + + + */ + public let type: Int // MessageType; + + /** + * The actual message + */ + public let message: String + } +} diff --git a/Sources/Packet/LSP.Packet.swift b/Sources/Packet/LSP.Packet.swift index f1fd0ec..008ef30 100644 --- a/Sources/Packet/LSP.Packet.swift +++ b/Sources/Packet/LSP.Packet.swift @@ -96,7 +96,7 @@ public extension LSP guard let separatorIndex = indexOfSeparator(in: data) else { - log(warning: "Data contains no header/content separator:\n\(data.utf8String!)") + log(warning: "Data (\(data.count) Byte) contains no header/content separator:\n\(data.utf8String!)") return nil } From a3fcd6daeb865a3db61c87ffce699b0536b1639f Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 28 Jun 2023 17:17:12 +0200 Subject: [PATCH 22/28] Update FoundationToolz --- Package.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 3e15898..e4bde6b 100644 --- a/Package.swift +++ b/Package.swift @@ -11,9 +11,10 @@ let package = Package( targets: ["SwiftLSP"]), ], dependencies: [ +// .package(path: "../FoundationToolz"), .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.3.1" + exact: "0.4.0" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", From d5f96eec86822d8f423c8bc2280d5b6c1bb0322a Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Wed, 28 Jun 2023 17:48:14 +0200 Subject: [PATCH 23/28] Adjust log level: failing to parse packet from still incomplete data is expected --- Sources/Packet/LSP.Packet.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Packet/LSP.Packet.swift b/Sources/Packet/LSP.Packet.swift index 008ef30..9bfd315 100644 --- a/Sources/Packet/LSP.Packet.swift +++ b/Sources/Packet/LSP.Packet.swift @@ -96,7 +96,7 @@ public extension LSP guard let separatorIndex = indexOfSeparator(in: data) else { - log(warning: "Data (\(data.count) Byte) contains no header/content separator:\n\(data.utf8String!)") + log(verbose: "Data (\(data.count) Byte) contains no header/content separator:\n\(data.utf8String!) (yet)") return nil } From f96fff04144faccadb1e862f6d30bc62a49b18e2 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 2 Jul 2023 13:15:37 +0200 Subject: [PATCH 24/28] Update FoundationToolz --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index e4bde6b..f3a0b7d 100644 --- a/Package.swift +++ b/Package.swift @@ -14,7 +14,7 @@ let package = Package( // .package(path: "../FoundationToolz"), .package( url: "https://github.com/flowtoolz/FoundationToolz.git", - exact: "0.4.0" + exact: "0.4.1" ), .package( url: "https://github.com/flowtoolz/SwiftyToolz.git", From 8f8e8c9cf4df5b286a9cfc43041fff54757bc7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20P=C3=A9russe?= Date: Sun, 6 Aug 2023 15:17:29 -0400 Subject: [PATCH 25/28] Add a public initializer for ErrorResult --- Sources/Message/LSP.Message.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/Message/LSP.Message.swift b/Sources/Message/LSP.Message.swift index 92d2d31..e8d4758 100644 --- a/Sources/Message/LSP.Message.swift +++ b/Sources/Message/LSP.Message.swift @@ -46,6 +46,13 @@ extension LSP public let code: Int public let message: String public let data: JSON? + + public init(code: Int, message: String, data: JSON?) + { + self.code = code + self.message = message + self.data = data + } } } From 5dafd4d1a2699636e307f9fd2d60a024a86e299c Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 6 Aug 2023 23:36:48 +0200 Subject: [PATCH 26/28] Keep dependence direction aligned with reading direction --- Sources/Message/LSP.Message.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Message/LSP.Message.swift b/Sources/Message/LSP.Message.swift index e8d4758..a929de3 100644 --- a/Sources/Message/LSP.Message.swift +++ b/Sources/Message/LSP.Message.swift @@ -43,16 +43,16 @@ extension LSP public struct ErrorResult: Error, Equatable { - public let code: Int - public let message: String - public let data: JSON? - - public init(code: Int, message: String, data: JSON?) + public init(code: Int, message: String, data: JSON? = nil) { self.code = code self.message = message self.data = data } + + public let code: Int + public let message: String + public let data: JSON? } } From 21f49e80cb3816c75e203baf408be3eca88739b9 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 6 Aug 2023 23:37:13 +0200 Subject: [PATCH 27/28] Add test file for testing existence of public API --- Sources/Message/LSP.Message.swift | 4 ++-- Tests/PublicAPITests.swift | 13 +++++++++++++ Tests/SwiftLSPTests.swift | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Tests/PublicAPITests.swift diff --git a/Sources/Message/LSP.Message.swift b/Sources/Message/LSP.Message.swift index a929de3..0579e89 100644 --- a/Sources/Message/LSP.Message.swift +++ b/Sources/Message/LSP.Message.swift @@ -69,7 +69,7 @@ extension LSP */ public struct Request: Equatable, Sendable { - public init(id: ID = ID(), method: String, params: JSON.Container?) + public init(id: ID = ID(), method: String, params: JSON.Container? = nil) { self.id = id self.method = method @@ -96,7 +96,7 @@ extension LSP */ public struct Notification: Equatable, Sendable { - public init(method: String, params: JSON.Container?) + public init(method: String, params: JSON.Container? = nil) { self.method = method self.params = params diff --git a/Tests/PublicAPITests.swift b/Tests/PublicAPITests.swift new file mode 100644 index 0000000..9c357dd --- /dev/null +++ b/Tests/PublicAPITests.swift @@ -0,0 +1,13 @@ +import SwiftLSP // Do not use @testable❗️ we wanna test public API here like a real client +import XCTest + +final class PublicAPITests: XCTestCase { + + func testCreatingLSPTypes() { + _ = LSP.Message.Request(method: "just do it!") + _ = LSP.Message.Response(id: .value(.string(.randomID())), + result: .success(.bool(true))) + _ = LSP.Message.Notification(method: "just wanted to say hi") + _ = LSP.ErrorResult(code: 1000, message: "some LSP error occured") + } +} diff --git a/Tests/SwiftLSPTests.swift b/Tests/SwiftLSPTests.swift index 777250b..cf44ca0 100644 --- a/Tests/SwiftLSPTests.swift +++ b/Tests/SwiftLSPTests.swift @@ -1,7 +1,7 @@ -import XCTest @testable import SwiftLSP import FoundationToolz import SwiftyToolz +import XCTest final class SwiftLSPTests: XCTestCase { From e156fc27cfb214c9cff79a5770542bd636a45102 Mon Sep 17 00:00:00 2001 From: Sebastian Fichtner Date: Sun, 6 Aug 2023 23:55:53 +0200 Subject: [PATCH 28/28] Remove Xcode byproducts from repository. Prune .gitignore. --- .gitignore | 91 +------------------ .../contents.xcworkspacedata | 7 -- 2 files changed, 2 insertions(+), 96 deletions(-) delete mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/.gitignore b/.gitignore index 7b8b548..02b285f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,90 +1,3 @@ -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## User settings -xcuserdata/ - -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) -*.xcscmblueprint -*.xccheckout - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ -DerivedData/ -*.moved-aside -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 - -## Obj-C/Swift specific -*.hmap - -## App packaging -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -Package.resolved -# *.xcodeproj -# -# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata -# hence it is not needed unless you have added a package configuration file to your project -# .swiftpm - +.swiftpm/ .build/ - -# CocoaPods -# -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# -# Pods/ -# -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build/ - -# Accio dependency management -Dependencies/ -.accio/ - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. -# Instead, use fastlane to re-generate the screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output - -# Code Injection -# -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ +Package.resolved \ No newline at end of file diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - -