From 77e2368e1610ce2ba8082d512d2536c0c0a91aca Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 01:05:35 +0100 Subject: [PATCH 01/14] Add macro expansion request --- Sources/LanguageServerProtocol/Messages.swift | 1 + .../Requests/MacroExpansionRequest.swift | 38 +++++++++++++++++++ .../SupportTypes/MacroExpansion.swift | 17 +++++++++ 3 files changed, 56 insertions(+) create mode 100644 Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift create mode 100644 Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift diff --git a/Sources/LanguageServerProtocol/Messages.swift b/Sources/LanguageServerProtocol/Messages.swift index 38c4c1d32..b8a3687dd 100644 --- a/Sources/LanguageServerProtocol/Messages.swift +++ b/Sources/LanguageServerProtocol/Messages.swift @@ -55,6 +55,7 @@ public let builtinRequests: [_RequestType.Type] = [ InlineValueRefreshRequest.self, InlineValueRequest.self, LinkedEditingRangeRequest.self, + MacroExpansionRequest.self, MonikersRequest.self, OpenInterfaceRequest.self, PollIndexRequest.self, diff --git a/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift new file mode 100644 index 000000000..7cd1bb760 --- /dev/null +++ b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +/// Request the expansion of the macro at a given use site. +/// **LSP Extension**. +/// +/// - Parameters: +/// - textDocument: The document in which the macro is used. +/// - position: The position at which the macro is used. +/// +/// - Returns: The macro expansion. +public struct MacroExpansionRequest: TextDocumentRequest, Hashable { + public static let method: String = "sourcekit-lsp/macroExpansion" + public typealias Response = MacroExpansion? + + /// The document in which the macro is used. + public var textDocument: TextDocumentIdentifier + + /// The position at which the macro is used. + public var position: Position + + public init( + textDocument: TextDocumentIdentifier, + position: Position + ) { + self.textDocument = textDocument + self.position = position + } +} diff --git a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift new file mode 100644 index 000000000..4cb773a11 --- /dev/null +++ b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +/// The expansion of a macro in a source file. +public struct MacroExpansion: ResponseType, Hashable { + /// The Swift code that the macro expands to. + public let expansion: String +} From a3d8eaafbfdc1db147fdafb7dad6bb485e2f5ded Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 01:09:30 +0100 Subject: [PATCH 02/14] Stub out macroExpansion implementation --- Sources/LanguageServerProtocol/CMakeLists.txt | 2 ++ Sources/SourceKitLSP/Clang/ClangLanguageServer.swift | 4 ++++ Sources/SourceKitLSP/SourceKitServer.swift | 10 ++++++++++ Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 5 +++++ Sources/SourceKitLSP/ToolchainLanguageServer.swift | 1 + 5 files changed, 22 insertions(+) diff --git a/Sources/LanguageServerProtocol/CMakeLists.txt b/Sources/LanguageServerProtocol/CMakeLists.txt index bac242a72..c262e035d 100644 --- a/Sources/LanguageServerProtocol/CMakeLists.txt +++ b/Sources/LanguageServerProtocol/CMakeLists.txt @@ -64,6 +64,7 @@ add_library(LanguageServerProtocol STATIC Requests/InlineValueRefreshRequest.swift Requests/InlineValueRequest.swift Requests/LinkedEditingRangeRequest.swift + Requests/MacroExpansionRequest.swift Requests/MonikersRequest.swift Requests/OpenInterfaceRequest.swift Requests/PollIndexRequest.swift @@ -107,6 +108,7 @@ add_library(LanguageServerProtocol STATIC SupportTypes/LocationLink.swift SupportTypes/LocationsOrLocationLinksResponse.swift SupportTypes/LSPAny.swift + SupportTypes/MacroExpansion.swift SupportTypes/MarkupContent.swift SupportTypes/NotebookCellTextDocumentFilter.swift SupportTypes/NotebookDocument.swift diff --git a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift index 609427f77..3731b5d70 100644 --- a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift +++ b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift @@ -572,6 +572,10 @@ extension ClangLanguageServerShim { return try await forwardRequestToClangd(req) } + func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { + return nil + } + func foldingRange(_ req: FoldingRangeRequest) async throws -> [FoldingRange]? { guard self.capabilities?.foldingRangeProvider?.isSupported ?? false else { return nil diff --git a/Sources/SourceKitLSP/SourceKitServer.swift b/Sources/SourceKitLSP/SourceKitServer.swift index eea1cfabc..3a3240186 100644 --- a/Sources/SourceKitLSP/SourceKitServer.swift +++ b/Sources/SourceKitLSP/SourceKitServer.swift @@ -624,6 +624,8 @@ extension SourceKitServer: MessageHandler { requestHandler: self.documentDiagnostic, fallback: .full(.init(items: [])) ) + case let request as Request: + await self.handleRequest(for: request, requestHandler: self.macroExpansion, fallback: nil) default: reply(.failure(ResponseError.methodNotFound(R.method))) } @@ -1386,6 +1388,14 @@ extension SourceKitServer { return try await languageService.documentDiagnostic(req) } + func macroExpansion( + _ request: MacroExpansionRequest, + workspace: Workspace, + languageService: ToolchainLanguageServer + ) async throws -> MacroExpansion? { + return try await languageService.macroExpansion(request) + } + /// Converts a location from the symbol index to an LSP location. /// /// - Parameter location: The symbol index location diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index bb48be76d..fbcf29995 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1299,6 +1299,11 @@ extension SwiftLanguageServer { return .full(RelatedFullDocumentDiagnosticReport(items: diagnostics)) } + public func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { + // TODO + return nil + } + public func executeCommand(_ req: ExecuteCommandRequest) async throws -> LSPAny? { // TODO: If there's support for several types of commands, we might need to structure this similarly to the code actions request. guard let sourceKitServer else { diff --git a/Sources/SourceKitLSP/ToolchainLanguageServer.swift b/Sources/SourceKitLSP/ToolchainLanguageServer.swift index 471a8e19e..1020c247e 100644 --- a/Sources/SourceKitLSP/ToolchainLanguageServer.swift +++ b/Sources/SourceKitLSP/ToolchainLanguageServer.swift @@ -104,6 +104,7 @@ public protocol ToolchainLanguageServer: AnyObject { func codeAction(_ req: CodeActionRequest) async throws -> CodeActionRequestResponse? func inlayHint(_ req: InlayHintRequest) async throws -> [InlayHint] func documentDiagnostic(_ req: DocumentDiagnosticsRequest) async throws -> DocumentDiagnosticReport + func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? // MARK: - Other From f4eef6a6c85796263c5da6954b55d5a7602633fb Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 02:41:01 +0100 Subject: [PATCH 03/14] Add stub implementation of `macroExpansion` --- .../SourceKitLSP/Swift/SwiftLanguageServer.swift | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index fbcf29995..8773f7905 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1300,7 +1300,20 @@ extension SwiftLanguageServer { } public func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { - // TODO + guard let snapshot = documentManager.latestSnapshot(req.textDocument.uri) else { + let msg = "failed to find snapshot for url \(req.textDocument.uri)" + log(msg) + throw ResponseError.unknown(msg) + } + + let syntaxTree = await syntaxTreeManager.syntaxTree(for: snapshot) + + // TODO: Traverse syntax tree, extract the moduleName, typeName and roles + // for the macro at the position given in the request. Use these to + // construct `ExpansionSpecifier`s and pass them to SourceKitD via + // the `syntacticMacroExpansion` function. Extract the text edits from the + // result and wrap them in `MacroExpansion`. + return nil } From a22e6c45862e1a453d5edc3955e6304d9c31f011 Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 11:35:20 +0100 Subject: [PATCH 04/14] Rename expansion to sourceText in MacroExpansion --- .../LanguageServerProtocol/SupportTypes/MacroExpansion.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift index 4cb773a11..10b0bef6e 100644 --- a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift +++ b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift @@ -13,5 +13,5 @@ /// The expansion of a macro in a source file. public struct MacroExpansion: ResponseType, Hashable { /// The Swift code that the macro expands to. - public let expansion: String + public let sourceText: String } From ceb4063fb42a9a13f83093df8ba7060752e0dad1 Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 11:50:38 +0100 Subject: [PATCH 05/14] Add public initializer to `MacroExpansion` --- .../LanguageServerProtocol/SupportTypes/MacroExpansion.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift index 10b0bef6e..2e4124863 100644 --- a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift +++ b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift @@ -14,4 +14,8 @@ public struct MacroExpansion: ResponseType, Hashable { /// The Swift code that the macro expands to. public let sourceText: String + + public init(sourceText: String) { + self.sourceText = sourceText + } } From 3ba673d2159a7c91b86110c5fc135e2a1491e110 Mon Sep 17 00:00:00 2001 From: fwcd Date: Wed, 11 Oct 2023 12:10:03 +0100 Subject: [PATCH 06/14] Update todo note --- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index 8773f7905..58f9c27ec 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1308,10 +1308,10 @@ extension SwiftLanguageServer { let syntaxTree = await syntaxTreeManager.syntaxTree(for: snapshot) - // TODO: Traverse syntax tree, extract the moduleName, typeName and roles - // for the macro at the position given in the request. Use these to - // construct `ExpansionSpecifier`s and pass them to SourceKitD via - // the `syntacticMacroExpansion` function. Extract the text edits from the + // TODO: Find the moduleName, typeName and roles for the macro at the + // position given in the request somehow. Use these to construct + // `ExpansionSpecifier`s and pass them to SourceKitD via the + // `syntacticMacroExpansion` function. Extract the text edits from the // result and wrap them in `MacroExpansion`. return nil From c03d10c1998a258aaa07964f2605c3458c25f538 Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 11:05:52 +0100 Subject: [PATCH 07/14] Use semantic refactoring to perform macro expansion --- .../Swift/SwiftLanguageServer.swift | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index 58f9c27ec..b7a865507 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1300,21 +1300,20 @@ extension SwiftLanguageServer { } public func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { - guard let snapshot = documentManager.latestSnapshot(req.textDocument.uri) else { - let msg = "failed to find snapshot for url \(req.textDocument.uri)" - log(msg) - throw ResponseError.unknown(msg) - } - - let syntaxTree = await syntaxTreeManager.syntaxTree(for: snapshot) + let command = SemanticRefactorCommand( + title: "Expand Macro", + actionString: "source.refactoring.kind.expand.macro", + positionRange: req.position.. LSPAny? { From 3a2427137d79a3761664703c341ba29f94da9c99 Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 11:08:15 +0100 Subject: [PATCH 08/14] Perform request on a position range --- .../Requests/MacroExpansionRequest.swift | 9 +++++---- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift index 7cd1bb760..3c823adaa 100644 --- a/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift +++ b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift @@ -15,7 +15,7 @@ /// /// - Parameters: /// - textDocument: The document in which the macro is used. -/// - position: The position at which the macro is used. +/// - range: The range at which the macro is used. /// /// - Returns: The macro expansion. public struct MacroExpansionRequest: TextDocumentRequest, Hashable { @@ -26,13 +26,14 @@ public struct MacroExpansionRequest: TextDocumentRequest, Hashable { public var textDocument: TextDocumentIdentifier /// The position at which the macro is used. - public var position: Position + @CustomCodable + public var range: Range public init( textDocument: TextDocumentIdentifier, - position: Position + range: Range ) { self.textDocument = textDocument - self.position = position + self._range = CustomCodable(wrappedValue: range) } } diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index b7a865507..d20dd2993 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1303,7 +1303,7 @@ extension SwiftLanguageServer { let command = SemanticRefactorCommand( title: "Expand Macro", actionString: "source.refactoring.kind.expand.macro", - positionRange: req.position.. Date: Fri, 13 Oct 2023 14:18:24 +0100 Subject: [PATCH 09/14] Return nil in macroExpansion if noEditsNeeded is thrown --- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index d20dd2993..665530772 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1307,13 +1307,17 @@ extension SwiftLanguageServer { textDocument: req.textDocument ) - let refactor = try await semanticRefactoring(command) + do { + let refactor = try await semanticRefactoring(command) - guard let newText = refactor.edit.changes?[req.textDocument.uri]?.first?.newText else { + guard let newText = refactor.edit.changes?[req.textDocument.uri]?.first?.newText else { + return nil + } + + return MacroExpansion(sourceText: newText) + } catch SemanticRefactoringError.noEditsNeeded(_) { return nil } - - return MacroExpansion(sourceText: newText) } public func executeCommand(_ req: ExecuteCommandRequest) async throws -> LSPAny? { From 150af0b1418e0ba3f64995522194b1073809748a Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 14:37:06 +0100 Subject: [PATCH 10/14] Return the position of the macro expansion --- .../SupportTypes/MacroExpansion.swift | 6 +++++- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift index 2e4124863..d1d48aabe 100644 --- a/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift +++ b/Sources/LanguageServerProtocol/SupportTypes/MacroExpansion.swift @@ -12,10 +12,14 @@ /// The expansion of a macro in a source file. public struct MacroExpansion: ResponseType, Hashable { + /// The position in the source file where the expansion would be inserted. + public let position: Position + /// The Swift code that the macro expands to. public let sourceText: String - public init(sourceText: String) { + public init(position: Position, sourceText: String) { + self.position = position self.sourceText = sourceText } } diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index 665530772..9fab8d671 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1310,11 +1310,14 @@ extension SwiftLanguageServer { do { let refactor = try await semanticRefactoring(command) - guard let newText = refactor.edit.changes?[req.textDocument.uri]?.first?.newText else { + guard let edit = refactor.edit.changes?[req.textDocument.uri]?.first else { return nil } - return MacroExpansion(sourceText: newText) + return MacroExpansion( + position: edit.range.lowerBound, + sourceText: edit.newText + ) } catch SemanticRefactoringError.noEditsNeeded(_) { return nil } From b72203007ffaf0cee94d255e08c4369d6845b2da Mon Sep 17 00:00:00 2001 From: fwcd <30873659+fwcd@users.noreply.github.com> Date: Fri, 13 Oct 2023 17:16:12 +0100 Subject: [PATCH 11/14] Fix small style issue Co-authored-by: Alex Hoppen --- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index 9fab8d671..f144e5cec 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1318,7 +1318,7 @@ extension SwiftLanguageServer { position: edit.range.lowerBound, sourceText: edit.newText ) - } catch SemanticRefactoringError.noEditsNeeded(_) { + } catch SemanticRefactoringError.noEditsNeeded { return nil } } From 424a4e1d8e07267a0140b48ac9302d3f0904575e Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 17:19:29 +0100 Subject: [PATCH 12/14] Add ResponseError.unsupportedMethod --- Sources/LanguageServerProtocol/Error.swift | 5 +++++ Sources/SourceKitLSP/Clang/ClangLanguageServer.swift | 2 +- Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Sources/LanguageServerProtocol/Error.swift b/Sources/LanguageServerProtocol/Error.swift index c2de5b598..de5972911 100644 --- a/Sources/LanguageServerProtocol/Error.swift +++ b/Sources/LanguageServerProtocol/Error.swift @@ -107,6 +107,11 @@ extension ResponseError { message: "request cancelled by server" ) + public static var unsupportedMethod: ResponseError = ResponseError( + code: .unknownErrorCode, + message: "unsupported method" + ) + public static func workspaceNotOpen(_ uri: DocumentURI) -> ResponseError { return ResponseError(code: .workspaceNotOpen, message: "No workspace containing '\(uri)' found") } diff --git a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift index 3731b5d70..7d7e90345 100644 --- a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift +++ b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift @@ -584,7 +584,7 @@ extension ClangLanguageServerShim { } func openInterface(_ request: OpenInterfaceRequest) async throws -> InterfaceDetails? { - throw ResponseError.unknown("unsupported method") + throw ResponseError.unsupportedMethod } // MARK: - Other diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index f144e5cec..d1e982978 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -577,11 +577,11 @@ extension SwiftLanguageServer { /// Returns true if the `ToolchainLanguageServer` will take ownership of the request. public func definition(_ request: DefinitionRequest) async throws -> LocationsOrLocationLinksResponse? { - throw ResponseError.unknown("unsupported method") + throw ResponseError.unsupportedMethod } public func declaration(_ request: DeclarationRequest) async throws -> LocationsOrLocationLinksResponse? { - throw ResponseError.unknown("unsupported method") + throw ResponseError.unsupportedMethod } public func hover(_ req: HoverRequest) async throws -> HoverResponse? { From 69c37876a2bccd67d1f7527a271ae0bbd3bf34c8 Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 17:20:02 +0100 Subject: [PATCH 13/14] Throw unsupportedMethod in ClangLanguageServer.macroExpansion Co-authored-by: Alex Hoppen --- Sources/SourceKitLSP/Clang/ClangLanguageServer.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift index 7d7e90345..f599c3881 100644 --- a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift +++ b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift @@ -573,7 +573,7 @@ extension ClangLanguageServerShim { } func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { - return nil + throw ResponseError.unsupportedMethod } func foldingRange(_ req: FoldingRangeRequest) async throws -> [FoldingRange]? { From 4e627a2b2b09eddf70329d0b7d1cff0e2f737023 Mon Sep 17 00:00:00 2001 From: fwcd Date: Fri, 13 Oct 2023 17:22:11 +0100 Subject: [PATCH 14/14] Respond with a list of macro expansions --- .../Requests/MacroExpansionRequest.swift | 2 +- .../Clang/ClangLanguageServer.swift | 2 +- Sources/SourceKitLSP/SourceKitServer.swift | 4 ++-- .../Swift/SwiftLanguageServer.swift | 18 ++++++++++-------- .../SourceKitLSP/ToolchainLanguageServer.swift | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift index 3c823adaa..2a3e37d43 100644 --- a/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift +++ b/Sources/LanguageServerProtocol/Requests/MacroExpansionRequest.swift @@ -20,7 +20,7 @@ /// - Returns: The macro expansion. public struct MacroExpansionRequest: TextDocumentRequest, Hashable { public static let method: String = "sourcekit-lsp/macroExpansion" - public typealias Response = MacroExpansion? + public typealias Response = [MacroExpansion] /// The document in which the macro is used. public var textDocument: TextDocumentIdentifier diff --git a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift index f599c3881..b1a258010 100644 --- a/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift +++ b/Sources/SourceKitLSP/Clang/ClangLanguageServer.swift @@ -572,7 +572,7 @@ extension ClangLanguageServerShim { return try await forwardRequestToClangd(req) } - func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { + func macroExpansion(_ req: MacroExpansionRequest) async throws -> [MacroExpansion] { throw ResponseError.unsupportedMethod } diff --git a/Sources/SourceKitLSP/SourceKitServer.swift b/Sources/SourceKitLSP/SourceKitServer.swift index 3a3240186..5892c03e2 100644 --- a/Sources/SourceKitLSP/SourceKitServer.swift +++ b/Sources/SourceKitLSP/SourceKitServer.swift @@ -625,7 +625,7 @@ extension SourceKitServer: MessageHandler { fallback: .full(.init(items: [])) ) case let request as Request: - await self.handleRequest(for: request, requestHandler: self.macroExpansion, fallback: nil) + await self.handleRequest(for: request, requestHandler: self.macroExpansion, fallback: []) default: reply(.failure(ResponseError.methodNotFound(R.method))) } @@ -1392,7 +1392,7 @@ extension SourceKitServer { _ request: MacroExpansionRequest, workspace: Workspace, languageService: ToolchainLanguageServer - ) async throws -> MacroExpansion? { + ) async throws -> [MacroExpansion] { return try await languageService.macroExpansion(request) } diff --git a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift index d1e982978..788a83b53 100644 --- a/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift +++ b/Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift @@ -1299,7 +1299,7 @@ extension SwiftLanguageServer { return .full(RelatedFullDocumentDiagnosticReport(items: diagnostics)) } - public func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? { + public func macroExpansion(_ req: MacroExpansionRequest) async throws -> [MacroExpansion] { let command = SemanticRefactorCommand( title: "Expand Macro", actionString: "source.refactoring.kind.expand.macro", @@ -1310,16 +1310,18 @@ extension SwiftLanguageServer { do { let refactor = try await semanticRefactoring(command) - guard let edit = refactor.edit.changes?[req.textDocument.uri]?.first else { - return nil + guard let edits = refactor.edit.changes?[req.textDocument.uri] else { + return [] } - return MacroExpansion( - position: edit.range.lowerBound, - sourceText: edit.newText - ) + return edits.map { edit in + MacroExpansion( + position: edit.range.lowerBound, + sourceText: edit.newText + ) + } } catch SemanticRefactoringError.noEditsNeeded { - return nil + return [] } } diff --git a/Sources/SourceKitLSP/ToolchainLanguageServer.swift b/Sources/SourceKitLSP/ToolchainLanguageServer.swift index 1020c247e..6d012a268 100644 --- a/Sources/SourceKitLSP/ToolchainLanguageServer.swift +++ b/Sources/SourceKitLSP/ToolchainLanguageServer.swift @@ -104,7 +104,7 @@ public protocol ToolchainLanguageServer: AnyObject { func codeAction(_ req: CodeActionRequest) async throws -> CodeActionRequestResponse? func inlayHint(_ req: InlayHintRequest) async throws -> [InlayHint] func documentDiagnostic(_ req: DocumentDiagnosticsRequest) async throws -> DocumentDiagnosticReport - func macroExpansion(_ req: MacroExpansionRequest) async throws -> MacroExpansion? + func macroExpansion(_ req: MacroExpansionRequest) async throws -> [MacroExpansion] // MARK: - Other