Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,22 @@ var targets: [Target] = [
swiftSettings: globalSwiftSettings
),

// MARK: DocCDocumentation
// MARK: DocumentationLanguageService

.target(
name: "DocumentationLanguageService",
dependencies: [
"BuildServerIntegration",
"DocCDocumentation",
"LanguageServerProtocol",
"SKUtilities",
"SourceKitLSP",
"SemanticIndex",
.product(name: "Markdown", package: "swift-markdown"),
],
exclude: [],
swiftSettings: globalSwiftSettings
),

.target(
name: "DocCDocumentation",
Expand All @@ -263,6 +278,7 @@ var targets: [Target] = [
dependencies: [
"BuildServerIntegration",
"ClangLanguageService",
"DocumentationLanguageService",
"LanguageServerProtocol",
"SKLogging",
"SKOptions",
Expand Down
10 changes: 3 additions & 7 deletions Sources/ClangLanguageService/ClangLanguageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ package import SwiftSyntax
import TSCExtensions
package import ToolchainRegistry

#if canImport(DocCDocumentation)
import DocCDocumentation
#endif

#if os(Windows)
import WinSDK
#endif
Expand Down Expand Up @@ -497,16 +493,16 @@ extension ClangLanguageService {
return try await forwardRequestToClangd(req)
}

#if canImport(DocCDocumentation)
package func doccDocumentation(_ req: DoccDocumentationRequest) async throws -> DoccDocumentationResponse {
guard let sourceKitLSPServer else {
throw ResponseError.unknown("Connection to the editor closed")
}

let snapshot = try sourceKitLSPServer.documentManager.latestSnapshot(req.textDocument.uri)
throw ResponseError.requestFailed(doccDocumentationError: .unsupportedLanguage(snapshot.language))
throw ResponseError.requestFailed(
"Documentation preview is not available for \(snapshot.language.description) files"
)
}
#endif

package func symbolInfo(_ req: SymbolInfoRequest) async throws -> [SymbolDetails] {
return try await forwardRequestToClangd(req)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Foundation
package import LanguageServerProtocol
import Markdown
import SKUtilities
import SourceKitLSP
import SemanticIndex

extension DocumentationLanguageService {
Expand Down Expand Up @@ -63,9 +64,13 @@ extension DocumentationLanguageService {
ofDocCSymbolLink: symbolLink,
fetchSymbolGraph: { location in
guard let symbolWorkspace = try await workspaceForDocument(uri: location.documentUri),
let languageService = try await languageService(for: location.documentUri, .swift, in: symbolWorkspace)
let languageService = await sourceKitLSPServer.languageService(
for: location.documentUri,
.swift,
in: symbolWorkspace
)
else {
throw ResponseError.internalError("Unable to find Swift language service for \(location.documentUri)")
throw ResponseError.internalError("Unable to find language service for \(location.documentUri)")
}
return try await languageService.symbolGraph(forOnDiskContentsOf: location.documentUri, at: location)
}
Expand All @@ -76,9 +81,13 @@ extension DocumentationLanguageService {
let symbolDocumentUri = symbolOccurrence.location.documentUri
guard
let symbolWorkspace = try await workspaceForDocument(uri: symbolDocumentUri),
let languageService = try await languageService(for: symbolDocumentUri, .swift, in: symbolWorkspace)
let languageService = await sourceKitLSPServer.languageService(
for: symbolDocumentUri,
.swift,
in: symbolWorkspace
)
else {
throw ResponseError.internalError("Unable to find Swift language service for \(symbolDocumentUri)")
throw ResponseError.internalError("Unable to find language service for \(symbolDocumentUri)")
}
let symbolGraph = try await languageService.symbolGraph(
forOnDiskContentsOf: symbolDocumentUri,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Foundation
package import IndexStoreDB
package import LanguageServerProtocol
package import SKOptions
package import SourceKitLSP
import SwiftExtensions
package import SwiftSyntax
package import ToolchainRegistry
Expand Down Expand Up @@ -52,7 +53,7 @@ package actor DocumentationLanguageService: LanguageService, Sendable {

func languageService(
for uri: DocumentURI,
_ language: Language,
_ language: LanguageServerProtocol.Language,
in workspace: Workspace
) async throws -> LanguageService? {
guard let sourceKitLSPServer else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ import LanguageServerProtocol
package import SourceKitLSP
import SwiftLanguageService

#if canImport(DocumentationLanguageService)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we not need to guard the DocumentationLanguageService use down below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do. Apparently I also added the check in a future commit that just didn’t make it into this PR 😂

import DocumentationLanguageService
#endif

extension LanguageServiceRegistry {
/// All types conforming to `LanguageService` that are known at compile time.
package static let staticallyKnownServices = {
var registry = LanguageServiceRegistry()
registry.register(ClangLanguageService.self, for: [.c, .cpp, .objective_c, .objective_cpp])
registry.register(SwiftLanguageService.self, for: [.swift])
#if canImport(DocumentationLanguageService)
registry.register(DocumentationLanguageService.self, for: [.markdown, .tutorial])
#endif
return registry
}()
}
7 changes: 7 additions & 0 deletions Sources/LanguageServerProtocol/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public struct ErrorCode: RawRepresentable, Codable, Hashable, Sendable {

// MARK: SourceKit-LSP specific error codes
public static let workspaceNotOpen: ErrorCode = ErrorCode(rawValue: -32003)

/// The method is not implemented in this `LanguageService`.
public static let requestNotImplemented: ErrorCode = ErrorCode(rawValue: -32004)
}

/// An error response represented by a code and message.
Expand Down Expand Up @@ -131,6 +134,10 @@ extension ResponseError {
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.
Expand Down
4 changes: 0 additions & 4 deletions Sources/SourceKitLSP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ add_library(SourceKitLSP STATIC
TextEdit+IsNoop.swift
Workspace.swift
)
target_sources(SourceKitLSP PRIVATE
Documentation/DocCDocumentationHandler.swift
Documentation/DocumentationLanguageService.swift
)
set_target_properties(SourceKitLSP PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}
)
Expand Down
2 changes: 0 additions & 2 deletions Sources/SourceKitLSP/LanguageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,7 @@ package protocol LanguageService: AnyObject, Sendable {
func completion(_ req: CompletionRequest) async throws -> CompletionList
func completionItemResolve(_ req: CompletionItemResolveRequest) async throws -> CompletionItem
func hover(_ req: HoverRequest) async throws -> HoverResponse?
#if canImport(DocCDocumentation)
func doccDocumentation(_ req: DoccDocumentationRequest) async throws -> DoccDocumentationResponse
#endif
func symbolInfo(_ request: SymbolInfoRequest) async throws -> [SymbolDetails]

/// Return the symbol graph at the given location for the contents of the document as they are on-disk (opposed to the
Expand Down
4 changes: 0 additions & 4 deletions Sources/SourceKitLSP/SourceKitLSPServer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -757,10 +757,8 @@ extension SourceKitLSPServer: QueueBasedMessageHandler {
await self.handleRequest(for: request, requestHandler: self.declaration)
case let request as RequestAndReply<DefinitionRequest>:
await self.handleRequest(for: request, requestHandler: self.definition)
#if canImport(DocCDocumentation)
case let request as RequestAndReply<DoccDocumentationRequest>:
await self.handleRequest(for: request, requestHandler: self.doccDocumentation)
#endif
case let request as RequestAndReply<DocumentColorRequest>:
await self.handleRequest(for: request, requestHandler: self.documentColor)
case let request as RequestAndReply<DocumentDiagnosticsRequest>:
Expand Down Expand Up @@ -1573,15 +1571,13 @@ extension SourceKitLSPServer {
return try await documentService(for: uri).completionItemResolve(request)
}

#if canImport(DocCDocumentation)
func doccDocumentation(
_ req: DoccDocumentationRequest,
workspace: Workspace,
languageService: LanguageService
) async throws -> DoccDocumentationResponse {
return try await languageService.doccDocumentation(req)
}
#endif

func hover(
_ req: HoverRequest,
Expand Down
17 changes: 12 additions & 5 deletions Sources/SwiftLanguageService/DoccDocumentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,23 @@
//
//===----------------------------------------------------------------------===//

#if canImport(DocCDocumentation)
import BuildServerIntegration
import DocCDocumentation
import Foundation
import IndexStoreDB
package import LanguageServerProtocol
import SemanticIndex
import SKLogging
import SemanticIndex
import SourceKitLSP
import SwiftExtensions
import SwiftSyntax
import SourceKitLSP

#if canImport(DocCDocumentation)
import DocCDocumentation
#endif

extension SwiftLanguageService {
package func doccDocumentation(_ req: DoccDocumentationRequest) async throws -> DoccDocumentationResponse {
#if canImport(DocCDocumentation)
guard let sourceKitLSPServer else {
throw ResponseError.internalError("SourceKit-LSP is shutting down")
}
Expand Down Expand Up @@ -100,8 +103,12 @@ extension SwiftLanguageService {
moduleName: moduleName,
catalogURL: catalogURL
)
#else
throw ResponseError.requestFailed("Documentation preview is not available in this build of SourceKit-LSP")
#endif
}

#if canImport(DocCDocumentation)
private func findMarkupExtensionFile(
workspace: Workspace,
documentationManager: DocCDocumentationManager,
Expand All @@ -127,6 +134,7 @@ extension SwiftLanguageService {
language: .markdown
)?.text
}
#endif
}

private struct DocumentableSymbol {
Expand Down Expand Up @@ -216,4 +224,3 @@ private struct DocumentableSymbol {
return nil
}
}
#endif
1 change: 0 additions & 1 deletion Tests/SourceKitLSPTests/DoccDocumentationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import SwiftDocC
import XCTest

final class DoccDocumentationTests: XCTestCase {

func testUnsupportedLanguage() async throws {
try await renderDocumentation(
markedText: "1️⃣",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

#if canImport(DocCDocumentation)
import LanguageServerProtocol
import SKTestSupport
import SourceKitLSP
Expand Down Expand Up @@ -39,3 +40,4 @@ private func assertHandles(language: Language) async throws {
)
XCTAssertEqual(completions, .init(isIncomplete: false, items: []))
}
#endif