mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-06 18:24:36 +01:00
This adds a sourcekitd plugin that drives the code completion requests. It also includes a `CompletionScoring` module that’s used to rank code completion results based on their contextual match, allowing us to show more relevant code completion results at the top.
92 lines
3.1 KiB
Swift
92 lines
3.1 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 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 Csourcekitd
|
|
import SourceKitD
|
|
|
|
/// Provide getters to get values of a sourcekitd request dictionary.
|
|
///
|
|
/// This is not part of the `SourceKitD` module because it uses `SourceKitD.servicePluginAPI` which must not be accessed
|
|
/// outside of the service plugin.
|
|
final class SKDRequestDictionaryReader: Sendable {
|
|
private nonisolated(unsafe) let dict: sourcekitd_api_object_t
|
|
let sourcekitd: SourceKitD
|
|
|
|
/// Creates an `SKDRequestDictionary` that essentially provides a view into the given opaque
|
|
/// `sourcekitd_api_object_t`.
|
|
init?(_ request: sourcekitd_api_object_t, sourcekitd: SourceKitD) {
|
|
guard sourcekitd.servicePluginApi.request_get_type(request) == SOURCEKITD_API_VARIANT_TYPE_DICTIONARY else {
|
|
return nil
|
|
}
|
|
self.dict = request
|
|
self.sourcekitd = sourcekitd
|
|
_ = sourcekitd.api.request_retain(dict)
|
|
}
|
|
|
|
deinit {
|
|
_ = sourcekitd.api.request_release(dict)
|
|
}
|
|
|
|
private func getVariant<T>(
|
|
_ key: sourcekitd_api_uid_t,
|
|
_ variantType: sourcekitd_api_variant_type_t,
|
|
_ retrievalFunction: (sourcekitd_api_object_t) -> T?
|
|
) -> T? {
|
|
guard let value = sourcekitd.servicePluginApi.request_dictionary_get_value(sourcekitd_api_object_t(dict), key)
|
|
else {
|
|
return nil
|
|
}
|
|
if sourcekitd.servicePluginApi.request_get_type(value) == variantType {
|
|
return retrievalFunction(value)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> String? {
|
|
return sourcekitd.servicePluginApi.request_dictionary_get_string(sourcekitd_api_object_t(dict), key).map(
|
|
String.init(cString:)
|
|
)
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> Int64? {
|
|
return getVariant(key, SOURCEKITD_API_VARIANT_TYPE_INT64, sourcekitd.servicePluginApi.request_int64_get_value)
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> Int? {
|
|
guard let value: Int64 = self[key] else {
|
|
return nil
|
|
}
|
|
return Int(value)
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> Bool? {
|
|
return getVariant(key, SOURCEKITD_API_VARIANT_TYPE_BOOL, sourcekitd.servicePluginApi.request_bool_get_value)
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> sourcekitd_api_uid_t? {
|
|
return sourcekitd.servicePluginApi.request_dictionary_get_uid(sourcekitd_api_object_t(dict), key)
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> SKDRequestArrayReader? {
|
|
return getVariant(key, SOURCEKITD_API_VARIANT_TYPE_ARRAY) {
|
|
SKDRequestArrayReader($0, sourcekitd: sourcekitd)
|
|
}
|
|
}
|
|
|
|
subscript(key: sourcekitd_api_uid_t) -> SKDRequestDictionaryReader? {
|
|
return getVariant(key, SOURCEKITD_API_VARIANT_TYPE_DICTIONARY) {
|
|
SKDRequestDictionaryReader($0, sourcekitd: sourcekitd)
|
|
}
|
|
}
|
|
}
|