mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
69 lines
2.7 KiB
Swift
69 lines
2.7 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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 IndexStoreDB
|
|
@_spi(SourceKitLSP) import LanguageServerProtocol
|
|
@_spi(SourceKitLSP) import SKLogging
|
|
|
|
/// Wrapper around `LanguageService.Type`, making it conform to `Hashable`.
|
|
struct LanguageServiceType: Hashable {
|
|
let type: any LanguageService.Type
|
|
|
|
init(_ type: any LanguageService.Type) {
|
|
self.type = type
|
|
}
|
|
|
|
static func == (lhs: LanguageServiceType, rhs: LanguageServiceType) -> Bool {
|
|
return ObjectIdentifier(lhs.type) == ObjectIdentifier(rhs.type)
|
|
}
|
|
|
|
func hash(into hasher: inout Hasher) {
|
|
hasher.combine(ObjectIdentifier(type))
|
|
}
|
|
}
|
|
|
|
/// Registry in which conformers to `LanguageService` can be registered to server semantic functionality for a set of
|
|
/// languages.
|
|
package struct LanguageServiceRegistry {
|
|
private var byLanguage: [Language: [LanguageServiceType]] = [:]
|
|
|
|
package init() {}
|
|
|
|
package mutating func register(_ languageService: any LanguageService.Type, for languages: [Language]) {
|
|
for language in languages {
|
|
let services = byLanguage[language] ?? []
|
|
if services.contains(LanguageServiceType(languageService)) {
|
|
logger.fault("\(languageService) already registered for \(language, privacy: .public)")
|
|
continue
|
|
}
|
|
byLanguage[language, default: []].append(LanguageServiceType(languageService))
|
|
}
|
|
}
|
|
|
|
/// The language services that can handle a document of the given language.
|
|
///
|
|
/// Multiple language services may be able to handle a document. Depending on the use case, callers need to combine
|
|
/// the results of the language services.
|
|
/// If it is possible to merge the results of the language service (eg. combining code actions from multiple language
|
|
/// services), that's the preferred choice.
|
|
/// Otherwise the language services occurring early in the array should be given precedence and the results of the
|
|
/// first language service that produces some should be returned.
|
|
func languageServices(for language: Language) -> [any LanguageService.Type] {
|
|
return byLanguage[language]?.map(\.type) ?? []
|
|
}
|
|
|
|
/// All language services that are registered in the registry.
|
|
var languageServices: Set<LanguageServiceType> {
|
|
return Set(byLanguage.values.flatMap { $0 })
|
|
}
|
|
}
|