Skip to content

Move SwiftLanguageService into its own module #2234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 14, 2025
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
55 changes: 45 additions & 10 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ var targets: [Target] = [
"SKLogging",
"SKOptions",
"SourceKitLSP",
"SwiftLanguageService",
"ToolchainRegistry",
"TSCExtensions",
],
Expand Down Expand Up @@ -464,6 +465,7 @@ var targets: [Target] = [
"SourceKitD",
"SourceKitLSP",
"SwiftExtensions",
"SwiftLanguageService",
"ToolchainRegistry",
"TSCExtensions",
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
Expand Down Expand Up @@ -533,17 +535,8 @@ var targets: [Target] = [
"ToolchainRegistry",
"TSCExtensions",
.product(name: "IndexStoreDB", package: "indexstore-db"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "Markdown", package: "swift-markdown"),
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
]
+ swiftPMDependency([
.product(name: "SwiftPM-auto", package: "swift-package-manager")
])
+ swiftSyntaxDependencies([
"SwiftBasicFormat", "SwiftDiagnostics", "SwiftIDEUtils", "SwiftParser", "SwiftParserDiagnostics",
"SwiftRefactor", "SwiftSyntax",
]),
] + swiftSyntaxDependencies(["SwiftSyntax"]),
exclude: ["CMakeLists.txt"],
swiftSettings: globalSwiftSettings
),
Expand Down Expand Up @@ -597,6 +590,48 @@ var targets: [Target] = [
swiftSettings: globalSwiftSettings
),

// MARK: SwiftLanguageService

.target(
name: "SwiftLanguageService",
dependencies: [
"BuildServerProtocol",
"BuildServerIntegration",
"Csourcekitd",
"DocCDocumentation",
"LanguageServerProtocol",
"LanguageServerProtocolExtensions",
"LanguageServerProtocolJSONRPC",
"SemanticIndex",
"SKLogging",
"SKOptions",
"SKUtilities",
"SourceKitD",
"SourceKitLSP",
"SwiftExtensions",
"ToolchainRegistry",
"TSCExtensions",
.product(name: "IndexStoreDB", package: "indexstore-db"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
]
+ swiftPMDependency([
.product(name: "SwiftPM-auto", package: "swift-package-manager")
])
+ swiftSyntaxDependencies([
"SwiftBasicFormat",
"SwiftDiagnostics",
"SwiftIDEUtils",
"SwiftParser",
"SwiftParserDiagnostics",
"SwiftRefactor",
"SwiftSyntax",
"SwiftSyntaxBuilder",
]),
exclude: ["CMakeLists.txt"],
swiftSettings: globalSwiftSettings
),

// MARK: SwiftSourceKitClientPlugin

.target(
Expand Down
7 changes: 4 additions & 3 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-package-name sourcekit_lsp>")
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-DRESILIENT_LIBRARIES>")
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-swift-version 6>")
add_subdirectory(BuildServerProtocol)
add_subdirectory(BuildServerIntegration)
add_subdirectory(BuildServerProtocol)
add_subdirectory(CAtomics)
add_subdirectory(CCompletionScoring)
add_subdirectory(ClangLanguageService)
Expand All @@ -17,10 +17,11 @@ add_subdirectory(SemanticIndex)
add_subdirectory(SKLogging)
add_subdirectory(SKOptions)
add_subdirectory(SKUtilities)
add_subdirectory(SourceKitLSP)
add_subdirectory(SourceKitD)
add_subdirectory(sourcekit-lsp)
add_subdirectory(SourceKitD)
add_subdirectory(SourceKitLSP)
add_subdirectory(SwiftExtensions)
add_subdirectory(SwiftLanguageService)
add_subdirectory(SwiftSourceKitClientPlugin)
add_subdirectory(SwiftSourceKitPlugin)
add_subdirectory(SwiftSourceKitPluginCommon)
Expand Down
18 changes: 16 additions & 2 deletions Sources/ClangLanguageService/ClangLanguageService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import BuildServerIntegration
import Foundation
package import IndexStoreDB
package import LanguageServerProtocol
import LanguageServerProtocolExtensions
import LanguageServerProtocolJSONRPC
Expand Down Expand Up @@ -100,14 +101,16 @@ package actor ClangLanguageService: LanguageService, MessageHandler {

/// The documents that have been opened and which language they have been
/// opened with.
private var openDocuments: [DocumentURI: Language] = [:]
private var openDocuments: [DocumentURI: LanguageServerProtocol.Language] = [:]

/// Type to map `clangd`'s semantic token legend to SourceKit-LSP's.
private var semanticTokensTranslator: SemanticTokensLegendTranslator? = nil

/// While `clangd` is running, its `Process` object.
private var clangdProcess: Process?

package static var builtInCommands: [String] { [] }

/// Creates a language server for the given client referencing the clang binary specified in `toolchain`.
/// Returns `nil` if `clangd` can't be found.
package init?(
Expand Down Expand Up @@ -500,7 +503,7 @@ extension ClangLanguageService {
throw ResponseError.unknown("Connection to the editor closed")
}

let snapshot = try await sourceKitLSPServer.documentManager.latestSnapshot(req.textDocument.uri)
let snapshot = try sourceKitLSPServer.documentManager.latestSnapshot(req.textDocument.uri)
throw ResponseError.requestFailed(doccDocumentationError: .unsupportedLanguage(snapshot.language))
}
#endif
Expand All @@ -509,6 +512,13 @@ extension ClangLanguageService {
return try await forwardRequestToClangd(req)
}

package func symbolGraph(
forOnDiskContentsOf symbolDocumentUri: DocumentURI,
at location: SymbolLocation
) async throws -> String? {
return nil
}

package func documentSymbolHighlight(_ req: DocumentHighlightRequest) async throws -> [DocumentHighlight]? {
return try await forwardRequestToClangd(req)
}
Expand Down Expand Up @@ -652,6 +662,10 @@ extension ClangLanguageService {
return nil
}

package static func syntacticTestItems(in uri: DocumentURI) async -> [AnnotatedTestItem] {
return []
}

package func editsToRename(
locations renameLocations: [RenameLocation],
in snapshot: DocumentSnapshot,
Expand Down
1 change: 1 addition & 0 deletions Sources/InProcessClient/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ target_link_libraries(InProcessClient PUBLIC
SKLogging
SKOptions
SourceKitLSP
SwiftLanguageService
ToolchainRegistry
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import ClangLanguageService
import LanguageServerProtocol
package import SourceKitLSP
import SwiftLanguageService

extension LanguageServiceRegistry {
/// All types conforming to `LanguageService` that are known at compile time.
Expand Down
3 changes: 2 additions & 1 deletion Sources/SKTestSupport/SkipUnless.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import SKLogging
import SourceKitD
import SourceKitLSP
import SwiftExtensions
import SwiftLanguageService
import TSCExtensions
import ToolchainRegistry
import XCTest
Expand Down Expand Up @@ -378,7 +379,7 @@ package actor SkipUnless {

let tokens = SyntaxHighlightingTokens(lspEncodedTokens: response.data)
return tokens.tokens.last
== SourceKitLSP.SyntaxHighlightingToken(
== SyntaxHighlightingToken(
range: Position(line: 1, utf16index: 4)..<Position(line: 1, utf16index: 11),
kind: .variable,
modifiers: []
Expand Down
77 changes: 14 additions & 63 deletions Sources/SourceKitLSP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ add_library(SourceKitLSP STATIC
DocumentManager.swift
DocumentSnapshot+FromFileContents.swift
DocumentSnapshot+PositionConversions.swift
GeneratedInterfaceDocumentURLData.swift
Hooks.swift
IndexProgressManager.swift
IndexStoreDB+MainFilesProvider.swift
LanguageServiceRegistry.swift
LanguageService.swift
LanguageServiceRegistry.swift
LogMessageNotification+representingStructureUsingEmojiPrefixIfNecessary.swift
MacroExpansionReferenceDocumentURLData.swift
MessageHandlingDependencyTracker.swift
ReferenceDocumentURL.swift
Rename.swift
SemanticTokensLegend+SourceKitLSPLegend.swift
SharedWorkDoneProgressManager.swift
SourceKitIndexDelegate.swift
SourceKitLSPCommandMetadata.swift
SourceKitLSPServer.swift
SymbolLocation+DocumentURI.swift
SyntacticTestIndex.swift
TestDiscovery.swift
TextEdit+IsNoop.swift
Workspace.swift
Expand All @@ -26,80 +30,27 @@ target_sources(SourceKitLSP PRIVATE
Documentation/DocCDocumentationHandler.swift
Documentation/DocumentationLanguageService.swift
)
target_sources(SourceKitLSP PRIVATE
Swift/AdjustPositionToStartOfIdentifier.swift
Swift/ClosureCompletionFormat.swift
Swift/CodeActions/AddDocumentation.swift
Swift/CodeActions/ConvertIntegerLiteral.swift
Swift/CodeActions/ConvertJSONToCodableStruct.swift
Swift/CodeActions/ConvertStringConcatenationToStringInterpolation.swift
Swift/CodeActions/PackageManifestEdits.swift
Swift/CodeActions/SyntaxCodeActionProvider.swift
Swift/CodeActions/SyntaxCodeActions.swift
Swift/CodeActions/SyntaxRefactoringCodeActionProvider.swift
Swift/CodeCompletion.swift
Swift/CodeCompletionSession.swift
Swift/CommentXML.swift
Swift/CursorInfo.swift
Swift/Diagnostic.swift
Swift/DiagnosticReportManager.swift
Swift/DocumentFormatting.swift
Swift/DocumentSymbols.swift
Swift/ExpandMacroCommand.swift
Swift/FoldingRange.swift
Swift/GeneratedInterfaceDocumentURLData.swift
Swift/GeneratedInterfaceManager.swift
Swift/GeneratedInterfaceManager.swift
Swift/MacroExpansion.swift
Swift/MacroExpansionReferenceDocumentURLData.swift
Swift/OpenInterface.swift
Swift/RefactoringEdit.swift
Swift/RefactoringResponse.swift
Swift/ReferenceDocumentURL.swift
Swift/RelatedIdentifiers.swift
Swift/RewriteSourceKitPlaceholders.swift
Swift/SemanticRefactorCommand.swift
Swift/SemanticRefactoring.swift
Swift/SemanticTokens.swift
Swift/SwiftCodeLensScanner.swift
Swift/SwiftCommand.swift
Swift/SwiftLanguageService.swift
Swift/SwiftTestingScanner.swift
Swift/SymbolInfo.swift
Swift/SyntacticSwiftXCTestScanner.swift
Swift/SyntacticTestIndex.swift
Swift/SyntaxHighlightingToken.swift
Swift/SyntaxHighlightingTokenParser.swift
Swift/SyntaxHighlightingTokens.swift
Swift/SyntaxTreeManager.swift
Swift/VariableTypeInfo.swift
Swift/WithSnapshotFromDiskOpenedInSourcekitd.swift
)
set_target_properties(SourceKitLSP PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}
)
target_link_libraries(SourceKitLSP PUBLIC
BuildServerProtocol
BuildServerIntegration
LanguageServerProtocol
LanguageServerProtocolExtensions
LanguageServerProtocolJSONRPC
SemanticIndex
SKLogging
SKOptions
SKUtilities
SourceKitD
SwiftExtensions
ToolchainRegistry
IndexStoreDB
SwiftSyntax::SwiftBasicFormat
SwiftSyntax::SwiftDiagnostics
SwiftSyntax::SwiftIDEUtils
SwiftSyntax::SwiftParser
SwiftSyntax::SwiftParserDiagnostics
SwiftSyntax::SwiftRefactor
SwiftSyntax::SwiftSyntax)
SwiftSyntax::SwiftSyntax
)
target_link_libraries(SourceKitLSP PRIVATE
PackageModelSyntax
LanguageServerProtocolJSONRPC
SKLogging
SourceKitD
TSCExtensions
$<$<NOT:$<PLATFORM_ID:Darwin>>:FoundationXML>)
$<$<NOT:$<PLATFORM_ID:Darwin>>:FoundationXML>
)

2 changes: 1 addition & 1 deletion Sources/SourceKitLSP/CapabilityRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import SwiftExtensions
/// capabilities.
package final actor CapabilityRegistry {
/// The client's capabilities as they were reported when sourcekit-lsp was launched.
package let clientCapabilities: ClientCapabilities
package nonisolated let clientCapabilities: ClientCapabilities

// MARK: Tracking capabilities dynamically registered in the client

Expand Down
17 changes: 0 additions & 17 deletions Sources/SourceKitLSP/DocumentSnapshot+PositionConversions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,23 +237,6 @@ extension DocumentSnapshot {
)
}

// MARK: Position <-> SourceKitDPosition

func sourcekitdPosition(
of position: Position,
callerFile: StaticString = #fileID,
callerLine: UInt = #line
) -> SourceKitDPosition {
let utf8Column = lineTable.utf8ColumnAt(
line: position.line,
utf16Column: position.utf16index,
callerFile: callerFile,
callerLine: callerLine
)
// FIXME: Introduce new type for UTF-8 based positions
return SourceKitDPosition(line: position.line + 1, utf8Column: utf8Column + 1)
}

// MAR: Position <-> SymbolLocation

/// Converts the given UTF-8-offset-based `SymbolLocation` to a UTF-16-based line:column `Position`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,10 @@ extension DocumentationLanguageService {
fetchSymbolGraph: { location in
guard let symbolWorkspace = try await workspaceForDocument(uri: location.documentUri),
let languageService = try await languageService(for: location.documentUri, .swift, in: symbolWorkspace)
as? SwiftLanguageService
else {
throw ResponseError.internalError("Unable to find Swift language service for \(location.documentUri)")
}
return try await languageService.withSnapshotFromDiskOpenedInSourcekitd(
uri: location.documentUri,
fallbackSettingsAfterTimeout: false
) { (snapshot, compileCommand) in
let (_, _, symbolGraph) = try await languageService.cursorInfo(
snapshot,
compileCommand: compileCommand,
Range(snapshot.position(of: location)),
includeSymbolGraph: true
)
return symbolGraph
}
return try await languageService.symbolGraph(forOnDiskContentsOf: location.documentUri, at: location)
}
)
else {
Expand All @@ -89,21 +77,13 @@ extension DocumentationLanguageService {
guard
let symbolWorkspace = try await workspaceForDocument(uri: symbolDocumentUri),
let languageService = try await languageService(for: symbolDocumentUri, .swift, in: symbolWorkspace)
as? SwiftLanguageService
else {
throw ResponseError.internalError("Unable to find Swift language service for \(symbolDocumentUri)")
}
let symbolGraph = try await languageService.withSnapshotFromDiskOpenedInSourcekitd(
uri: symbolDocumentUri,
fallbackSettingsAfterTimeout: false
) { snapshot, compileCommand in
try await languageService.cursorInfo(
snapshot,
compileCommand: compileCommand,
Range(snapshot.position(of: symbolOccurrence.location)),
includeSymbolGraph: true
).symbolGraph
}
let symbolGraph = try await languageService.symbolGraph(
forOnDiskContentsOf: symbolDocumentUri,
at: symbolOccurrence.location
)
guard let symbolGraph else {
throw ResponseError.internalError("Unable to retrieve symbol graph for \(symbolOccurrence.symbol.name)")
}
Expand Down
Loading