mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Add remaining foldingRange protocol capabilities Sending offset data to folding requests FoldingRange test Support folding comments Add test for folded comments
619 lines
29 KiB
Swift
619 lines
29 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2018 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 LanguageServerProtocol
|
|
import Basic
|
|
import SKSupport
|
|
import sourcekitd
|
|
|
|
/// A wrapper for accessing the API of a sourcekitd library loaded via `dlopen`.
|
|
final class SwiftSourceKitFramework {
|
|
|
|
/// The path to the sourcekitd dylib.
|
|
let path: AbsolutePath
|
|
|
|
/// The handle to the dylib.
|
|
let dylib: DLHandle
|
|
|
|
/// The sourcekitd API functions.
|
|
let api: sourcekitd_functions_t
|
|
|
|
/// Convenience for accessing known keys.
|
|
let keys: sourcekitd_keys
|
|
|
|
/// Convenience for accessing known keys.
|
|
let requests: sourcekitd_requests
|
|
|
|
/// Convenience for accessing known keys.
|
|
let values: sourcekitd_values
|
|
|
|
enum Error: Swift.Error {
|
|
case missingRequiredSymbol(String)
|
|
}
|
|
|
|
init(dylib path: AbsolutePath) throws {
|
|
self.path = path
|
|
self.dylib = try dlopen(path.asString, mode: [.lazy, .local, .first, .deepBind])
|
|
|
|
func dlsym_required<T>(_ handle: DLHandle, symbol: String) throws -> T {
|
|
guard let sym: T = dlsym(handle, symbol: symbol) else {
|
|
throw Error.missingRequiredSymbol(symbol)
|
|
}
|
|
return sym
|
|
}
|
|
|
|
// Workaround rdar://problem/43656704 by not constructing the value directly.
|
|
// self.api = sourcekitd_functions_t(
|
|
let ptr = UnsafeMutablePointer<sourcekitd_functions_t>.allocate(capacity: 1)
|
|
bzero(UnsafeMutableRawPointer(ptr), MemoryLayout<sourcekitd_functions_t>.stride)
|
|
var api = ptr.pointee
|
|
ptr.deallocate()
|
|
|
|
// The following crashes the compiler rdar://43658464
|
|
// api.variant_dictionary_apply = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_apply")
|
|
// api.variant_array_apply = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_apply")
|
|
|
|
api.initialize = try dlsym_required(dylib, symbol: "sourcekitd_initialize")
|
|
api.shutdown = try dlsym_required(dylib, symbol: "sourcekitd_shutdown")
|
|
api.uid_get_from_cstr = try dlsym_required(dylib, symbol: "sourcekitd_uid_get_from_cstr")
|
|
api.uid_get_from_buf = try dlsym_required(dylib, symbol: "sourcekitd_uid_get_from_buf")
|
|
api.uid_get_length = try dlsym_required(dylib, symbol: "sourcekitd_uid_get_length")
|
|
api.uid_get_string_ptr = try dlsym_required(dylib, symbol: "sourcekitd_uid_get_string_ptr")
|
|
api.request_retain = try dlsym_required(dylib, symbol: "sourcekitd_request_retain")
|
|
api.request_release = try dlsym_required(dylib, symbol: "sourcekitd_request_release")
|
|
api.request_dictionary_create = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_create")
|
|
api.request_dictionary_set_value = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_set_value")
|
|
api.request_dictionary_set_string = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_set_string")
|
|
api.request_dictionary_set_stringbuf = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_set_stringbuf")
|
|
api.request_dictionary_set_int64 = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_set_int64")
|
|
api.request_dictionary_set_uid = try dlsym_required(dylib, symbol: "sourcekitd_request_dictionary_set_uid")
|
|
api.request_array_create = try dlsym_required(dylib, symbol: "sourcekitd_request_array_create")
|
|
api.request_array_set_value = try dlsym_required(dylib, symbol: "sourcekitd_request_array_set_value")
|
|
api.request_array_set_string = try dlsym_required(dylib, symbol: "sourcekitd_request_array_set_string")
|
|
api.request_array_set_stringbuf = try dlsym_required(dylib, symbol: "sourcekitd_request_array_set_stringbuf")
|
|
api.request_array_set_int64 = try dlsym_required(dylib, symbol: "sourcekitd_request_array_set_int64")
|
|
api.request_array_set_uid = try dlsym_required(dylib, symbol: "sourcekitd_request_array_set_uid")
|
|
api.request_int64_create = try dlsym_required(dylib, symbol: "sourcekitd_request_int64_create")
|
|
api.request_string_create = try dlsym_required(dylib, symbol: "sourcekitd_request_string_create")
|
|
api.request_uid_create = try dlsym_required(dylib, symbol: "sourcekitd_request_uid_create")
|
|
api.request_create_from_yaml = try dlsym_required(dylib, symbol: "sourcekitd_request_create_from_yaml")
|
|
api.request_description_dump = try dlsym_required(dylib, symbol: "sourcekitd_request_description_dump")
|
|
api.request_description_copy = try dlsym_required(dylib, symbol: "sourcekitd_request_description_copy")
|
|
api.response_dispose = try dlsym_required(dylib, symbol: "sourcekitd_response_dispose")
|
|
api.response_is_error = try dlsym_required(dylib, symbol: "sourcekitd_response_is_error")
|
|
api.response_error_get_kind = try dlsym_required(dylib, symbol: "sourcekitd_response_error_get_kind")
|
|
api.response_error_get_description = try dlsym_required(dylib, symbol: "sourcekitd_response_error_get_description")
|
|
api.response_get_value = try dlsym_required(dylib, symbol: "sourcekitd_response_get_value")
|
|
api.variant_get_type = try dlsym_required(dylib, symbol: "sourcekitd_variant_get_type")
|
|
api.variant_dictionary_get_value = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_get_value")
|
|
api.variant_dictionary_get_string = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_get_string")
|
|
api.variant_dictionary_get_int64 = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_get_int64")
|
|
api.variant_dictionary_get_bool = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_get_bool")
|
|
api.variant_dictionary_get_uid = try dlsym_required(dylib, symbol: "sourcekitd_variant_dictionary_get_uid")
|
|
|
|
api.variant_array_get_count = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_count")
|
|
api.variant_array_get_value = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_value")
|
|
api.variant_array_get_string = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_string")
|
|
api.variant_array_get_int64 = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_int64")
|
|
api.variant_array_get_bool = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_bool")
|
|
api.variant_array_get_uid = try dlsym_required(dylib, symbol: "sourcekitd_variant_array_get_uid")
|
|
|
|
api.variant_int64_get_value = try dlsym_required(dylib, symbol: "sourcekitd_variant_int64_get_value")
|
|
api.variant_bool_get_value = try dlsym_required(dylib, symbol: "sourcekitd_variant_bool_get_value")
|
|
api.variant_string_get_length = try dlsym_required(dylib, symbol: "sourcekitd_variant_string_get_length")
|
|
api.variant_string_get_ptr = try dlsym_required(dylib, symbol: "sourcekitd_variant_string_get_ptr")
|
|
api.variant_data_get_size = dlsym(dylib, symbol: "sourcekitd_variant_data_get_size") // Optional
|
|
api.variant_data_get_ptr = dlsym(dylib, symbol: "sourcekitd_variant_data_get_ptr") // Optional
|
|
api.variant_uid_get_value = try dlsym_required(dylib, symbol: "sourcekitd_variant_uid_get_value")
|
|
api.response_description_dump = try dlsym_required(dylib, symbol: "sourcekitd_response_description_dump")
|
|
api.response_description_dump_filedesc = try dlsym_required(dylib, symbol: "sourcekitd_response_description_dump_filedesc")
|
|
api.response_description_copy = try dlsym_required(dylib, symbol: "sourcekitd_response_description_copy")
|
|
api.variant_description_dump = try dlsym_required(dylib, symbol: "sourcekitd_variant_description_dump")
|
|
api.variant_description_dump_filedesc = try dlsym_required(dylib, symbol: "sourcekitd_variant_description_dump_filedesc")
|
|
api.variant_description_copy = try dlsym_required(dylib, symbol: "sourcekitd_variant_description_copy")
|
|
api.send_request_sync = try dlsym_required(dylib, symbol: "sourcekitd_send_request_sync")
|
|
api.send_request = try dlsym_required(dylib, symbol: "sourcekitd_send_request")
|
|
api.cancel_request = try dlsym_required(dylib, symbol: "sourcekitd_cancel_request")
|
|
api.set_notification_handler = try dlsym_required(dylib, symbol: "sourcekitd_set_notification_handler")
|
|
api.set_uid_handlers = try dlsym_required(dylib, symbol: "sourcekitd_set_uid_handlers")
|
|
|
|
self.api = api
|
|
|
|
self.keys = sourcekitd_keys(api: self.api)
|
|
self.requests = sourcekitd_requests(api: self.api)
|
|
self.values = sourcekitd_values(api: self.api)
|
|
}
|
|
|
|
deinit {
|
|
// FIXME: is it safe to dlclose() sourcekitd? If so, do that here. For now, let the handle leak.
|
|
dylib.leak()
|
|
}
|
|
}
|
|
|
|
extension SwiftSourceKitFramework {
|
|
|
|
// MARK: - Convenience API for requests.
|
|
|
|
/// Send the given request and synchronously receive a reply dictionary (or error).
|
|
func sendSync(_ req: SKRequestDictionary) -> LSPResult<SKResponseDictionary> {
|
|
logAsync { _ in req.description }
|
|
|
|
let resp = SKResponse(api.send_request_sync(req.dict), sourcekitd: self)
|
|
|
|
guard let dict = resp.value else {
|
|
log(resp.description, level: .error)
|
|
return .failure(resp.error!)
|
|
}
|
|
|
|
logAsync(level: .debug) { _ in dict.description }
|
|
|
|
return .success(dict)
|
|
}
|
|
|
|
/// Send the given request and synchronously receive a reply dictionary (or error).
|
|
func send(_ req: SKRequestDictionary, reply: @escaping (LSPResult<SKResponseDictionary>) -> ()) -> sourcekitd_request_handle_t? {
|
|
logAsync { _ in req.description }
|
|
|
|
var handle: sourcekitd_request_handle_t? = nil
|
|
|
|
api.send_request(req.dict, &handle) { [weak self] _resp in
|
|
guard let self = self else { return }
|
|
|
|
let resp = SKResponse(_resp, sourcekitd: self)
|
|
|
|
guard let dict = resp.value else {
|
|
log(resp.description, level: .error)
|
|
reply(.failure(resp.error!))
|
|
return
|
|
}
|
|
|
|
logAsync(level: .debug) { _ in dict.description }
|
|
|
|
reply(.success(dict))
|
|
}
|
|
|
|
return handle
|
|
}
|
|
|
|
}
|
|
|
|
struct sourcekitd_keys {
|
|
|
|
let request: sourcekitd_uid_t
|
|
let compilerargs: sourcekitd_uid_t
|
|
let offset: sourcekitd_uid_t
|
|
let length: sourcekitd_uid_t
|
|
let sourcefile: sourcekitd_uid_t
|
|
let sourcetext: sourcekitd_uid_t
|
|
let results: sourcekitd_uid_t
|
|
let description: sourcekitd_uid_t
|
|
let name: sourcekitd_uid_t
|
|
let kind: sourcekitd_uid_t
|
|
let notification: sourcekitd_uid_t
|
|
let diagnostics: sourcekitd_uid_t
|
|
let severity: sourcekitd_uid_t
|
|
let line: sourcekitd_uid_t
|
|
let column: sourcekitd_uid_t
|
|
let filepath: sourcekitd_uid_t
|
|
let ranges: sourcekitd_uid_t
|
|
let usr: sourcekitd_uid_t
|
|
let annotated_decl: sourcekitd_uid_t
|
|
let doc_full_as_xml: sourcekitd_uid_t
|
|
let syntactic_only: sourcekitd_uid_t
|
|
let substructure: sourcekitd_uid_t
|
|
let bodyoffset: sourcekitd_uid_t
|
|
let bodylength: sourcekitd_uid_t
|
|
let syntaxmap: sourcekitd_uid_t
|
|
|
|
init(api: sourcekitd_functions_t) {
|
|
request = api.uid_get_from_cstr("key.request")!
|
|
compilerargs = api.uid_get_from_cstr("key.compilerargs")!
|
|
offset = api.uid_get_from_cstr("key.offset")!
|
|
length = api.uid_get_from_cstr("key.length")!
|
|
sourcefile = api.uid_get_from_cstr("key.sourcefile")!
|
|
sourcetext = api.uid_get_from_cstr("key.sourcetext")!
|
|
results = api.uid_get_from_cstr("key.results")!
|
|
description = api.uid_get_from_cstr("key.description")!
|
|
name = api.uid_get_from_cstr("key.name")!
|
|
kind = api.uid_get_from_cstr("key.kind")!
|
|
notification = api.uid_get_from_cstr("key.notification")!
|
|
diagnostics = api.uid_get_from_cstr("key.diagnostics")!
|
|
severity = api.uid_get_from_cstr("key.severity")!
|
|
line = api.uid_get_from_cstr("key.line")!
|
|
column = api.uid_get_from_cstr("key.column")!
|
|
filepath = api.uid_get_from_cstr("key.filepath")!
|
|
ranges = api.uid_get_from_cstr("key.ranges")!
|
|
usr = api.uid_get_from_cstr("key.usr")!
|
|
annotated_decl = api.uid_get_from_cstr("key.annotated_decl")!
|
|
doc_full_as_xml = api.uid_get_from_cstr("key.doc.full_as_xml")!
|
|
syntactic_only = api.uid_get_from_cstr("key.syntactic_only")!
|
|
substructure = api.uid_get_from_cstr("key.substructure")!
|
|
bodyoffset = api.uid_get_from_cstr("key.bodyoffset")!
|
|
bodylength = api.uid_get_from_cstr("key.bodylength")!
|
|
syntaxmap = api.uid_get_from_cstr("key.syntaxmap")!
|
|
}
|
|
}
|
|
|
|
struct sourcekitd_requests {
|
|
|
|
let editor_open: sourcekitd_uid_t
|
|
let editor_close: sourcekitd_uid_t
|
|
let editor_replacetext: sourcekitd_uid_t
|
|
let codecomplete: sourcekitd_uid_t
|
|
let cursorinfo: sourcekitd_uid_t
|
|
let relatedidents: sourcekitd_uid_t
|
|
|
|
init(api: sourcekitd_functions_t) {
|
|
editor_open = api.uid_get_from_cstr("source.request.editor.open")!
|
|
editor_close = api.uid_get_from_cstr("source.request.editor.close")!
|
|
editor_replacetext = api.uid_get_from_cstr("source.request.editor.replacetext")!
|
|
codecomplete = api.uid_get_from_cstr("source.request.codecomplete")!
|
|
cursorinfo = api.uid_get_from_cstr("source.request.cursorinfo")!
|
|
relatedidents = api.uid_get_from_cstr("source.request.relatedidents")!
|
|
}
|
|
}
|
|
|
|
struct sourcekitd_values {
|
|
|
|
let notification_documentupdate: sourcekitd_uid_t
|
|
let diag_error: sourcekitd_uid_t
|
|
let diag_warning: sourcekitd_uid_t
|
|
let diag_note: sourcekitd_uid_t
|
|
|
|
// MARK: Symbol Kinds
|
|
|
|
let decl_function_free: sourcekitd_uid_t
|
|
let ref_function_free: sourcekitd_uid_t
|
|
let decl_function_method_instance: sourcekitd_uid_t
|
|
let ref_function_method_instance: sourcekitd_uid_t
|
|
let decl_function_method_static: sourcekitd_uid_t
|
|
let ref_function_method_static: sourcekitd_uid_t
|
|
let decl_function_method_class: sourcekitd_uid_t
|
|
let ref_function_method_class: sourcekitd_uid_t
|
|
let decl_function_accessor_getter: sourcekitd_uid_t
|
|
let ref_function_accessor_getter: sourcekitd_uid_t
|
|
let decl_function_accessor_setter: sourcekitd_uid_t
|
|
let ref_function_accessor_setter: sourcekitd_uid_t
|
|
let decl_function_accessor_willset: sourcekitd_uid_t
|
|
let ref_function_accessor_willset: sourcekitd_uid_t
|
|
let decl_function_accessor_didset: sourcekitd_uid_t
|
|
let ref_function_accessor_didset: sourcekitd_uid_t
|
|
let decl_function_accessor_address: sourcekitd_uid_t
|
|
let ref_function_accessor_address: sourcekitd_uid_t
|
|
let decl_function_accessor_mutableaddress: sourcekitd_uid_t
|
|
let ref_function_accessor_mutableaddress: sourcekitd_uid_t
|
|
let decl_function_accessor_read: sourcekitd_uid_t
|
|
let ref_function_accessor_read: sourcekitd_uid_t
|
|
let decl_function_accessor_modify: sourcekitd_uid_t
|
|
let ref_function_accessor_modify: sourcekitd_uid_t
|
|
let decl_function_constructor: sourcekitd_uid_t
|
|
let ref_function_constructor: sourcekitd_uid_t
|
|
let decl_function_destructor: sourcekitd_uid_t
|
|
let ref_function_destructor: sourcekitd_uid_t
|
|
let decl_function_operator_prefix: sourcekitd_uid_t
|
|
let decl_function_operator_postfix: sourcekitd_uid_t
|
|
let decl_function_operator_infix: sourcekitd_uid_t
|
|
let ref_function_operator_prefix: sourcekitd_uid_t
|
|
let ref_function_operator_postfix: sourcekitd_uid_t
|
|
let ref_function_operator_infix: sourcekitd_uid_t
|
|
let decl_precedencegroup: sourcekitd_uid_t
|
|
let ref_precedencegroup: sourcekitd_uid_t
|
|
let decl_function_subscript: sourcekitd_uid_t
|
|
let ref_function_subscript: sourcekitd_uid_t
|
|
let decl_var_global: sourcekitd_uid_t
|
|
let ref_var_global: sourcekitd_uid_t
|
|
let decl_var_instance: sourcekitd_uid_t
|
|
let ref_var_instance: sourcekitd_uid_t
|
|
let decl_var_static: sourcekitd_uid_t
|
|
let ref_var_static: sourcekitd_uid_t
|
|
let decl_var_class: sourcekitd_uid_t
|
|
let ref_var_class: sourcekitd_uid_t
|
|
let decl_var_local: sourcekitd_uid_t
|
|
let ref_var_local: sourcekitd_uid_t
|
|
let decl_var_parameter: sourcekitd_uid_t
|
|
let decl_module: sourcekitd_uid_t
|
|
let decl_class: sourcekitd_uid_t
|
|
let ref_class: sourcekitd_uid_t
|
|
let decl_struct: sourcekitd_uid_t
|
|
let ref_struct: sourcekitd_uid_t
|
|
let decl_enum: sourcekitd_uid_t
|
|
let ref_enum: sourcekitd_uid_t
|
|
let decl_enumcase: sourcekitd_uid_t
|
|
let decl_enumelement: sourcekitd_uid_t
|
|
let ref_enumelement: sourcekitd_uid_t
|
|
let decl_protocol: sourcekitd_uid_t
|
|
let ref_protocol: sourcekitd_uid_t
|
|
let decl_extension: sourcekitd_uid_t
|
|
let decl_extension_struct: sourcekitd_uid_t
|
|
let decl_extension_class: sourcekitd_uid_t
|
|
let decl_extension_enum: sourcekitd_uid_t
|
|
let decl_extension_protocol: sourcekitd_uid_t
|
|
let decl_associatedtype: sourcekitd_uid_t
|
|
let ref_associatedtype: sourcekitd_uid_t
|
|
let decl_typealias: sourcekitd_uid_t
|
|
let ref_typealias: sourcekitd_uid_t
|
|
let decl_generic_type_param: sourcekitd_uid_t
|
|
let ref_generic_type_param: sourcekitd_uid_t
|
|
let ref_module: sourcekitd_uid_t
|
|
let syntaxtype_comment: sourcekitd_uid_t
|
|
|
|
let kind_keyword: sourcekitd_uid_t
|
|
|
|
init(api: sourcekitd_functions_t) {
|
|
notification_documentupdate = api.uid_get_from_cstr("source.notification.editor.documentupdate")!
|
|
diag_error = api.uid_get_from_cstr("source.diagnostic.severity.error")!
|
|
diag_warning = api.uid_get_from_cstr("source.diagnostic.severity.warning")!
|
|
diag_note = api.uid_get_from_cstr("source.diagnostic.severity.note")!
|
|
|
|
// MARK: Symbol Kinds
|
|
|
|
decl_function_free = api.uid_get_from_cstr("source.lang.swift.decl.function.free")!
|
|
ref_function_free = api.uid_get_from_cstr("source.lang.swift.ref.function.free")!
|
|
decl_function_method_instance = api.uid_get_from_cstr("source.lang.swift.decl.function.method.instance")!
|
|
ref_function_method_instance = api.uid_get_from_cstr("source.lang.swift.ref.function.method.instance")!
|
|
decl_function_method_static = api.uid_get_from_cstr("source.lang.swift.decl.function.method.static")!
|
|
ref_function_method_static = api.uid_get_from_cstr("source.lang.swift.ref.function.method.static")!
|
|
decl_function_method_class = api.uid_get_from_cstr("source.lang.swift.decl.function.method.class")!
|
|
ref_function_method_class = api.uid_get_from_cstr("source.lang.swift.ref.function.method.class")!
|
|
decl_function_accessor_getter = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.getter")!
|
|
ref_function_accessor_getter = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.getter")!
|
|
decl_function_accessor_setter = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.setter")!
|
|
ref_function_accessor_setter = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.setter")!
|
|
decl_function_accessor_willset = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.willset")!
|
|
ref_function_accessor_willset = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.willset")!
|
|
decl_function_accessor_didset = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.didset")!
|
|
ref_function_accessor_didset = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.didset")!
|
|
decl_function_accessor_address = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.address")!
|
|
ref_function_accessor_address = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.address")!
|
|
decl_function_accessor_mutableaddress = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.mutableaddress")!
|
|
ref_function_accessor_mutableaddress = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.mutableaddress")!
|
|
decl_function_accessor_read = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.read")!
|
|
ref_function_accessor_read = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.read")!
|
|
decl_function_accessor_modify = api.uid_get_from_cstr("source.lang.swift.decl.function.accessor.modify")!
|
|
ref_function_accessor_modify = api.uid_get_from_cstr("source.lang.swift.ref.function.accessor.modify")!
|
|
decl_function_constructor = api.uid_get_from_cstr("source.lang.swift.decl.function.constructor")!
|
|
ref_function_constructor = api.uid_get_from_cstr("source.lang.swift.ref.function.constructor")!
|
|
decl_function_destructor = api.uid_get_from_cstr("source.lang.swift.decl.function.destructor")!
|
|
ref_function_destructor = api.uid_get_from_cstr("source.lang.swift.ref.function.destructor")!
|
|
decl_function_operator_prefix = api.uid_get_from_cstr("source.lang.swift.decl.function.operator.prefix")!
|
|
decl_function_operator_postfix = api.uid_get_from_cstr("source.lang.swift.decl.function.operator.postfix")!
|
|
decl_function_operator_infix = api.uid_get_from_cstr("source.lang.swift.decl.function.operator.infix")!
|
|
ref_function_operator_prefix = api.uid_get_from_cstr("source.lang.swift.ref.function.operator.prefix")!
|
|
ref_function_operator_postfix = api.uid_get_from_cstr("source.lang.swift.ref.function.operator.postfix")!
|
|
ref_function_operator_infix = api.uid_get_from_cstr("source.lang.swift.ref.function.operator.infix")!
|
|
decl_precedencegroup = api.uid_get_from_cstr("source.lang.swift.decl.precedencegroup")!
|
|
ref_precedencegroup = api.uid_get_from_cstr("source.lang.swift.ref.precedencegroup")!
|
|
decl_function_subscript = api.uid_get_from_cstr("source.lang.swift.decl.function.subscript")!
|
|
ref_function_subscript = api.uid_get_from_cstr("source.lang.swift.ref.function.subscript")!
|
|
decl_var_global = api.uid_get_from_cstr("source.lang.swift.decl.var.global")!
|
|
ref_var_global = api.uid_get_from_cstr("source.lang.swift.ref.var.global")!
|
|
decl_var_instance = api.uid_get_from_cstr("source.lang.swift.decl.var.instance")!
|
|
ref_var_instance = api.uid_get_from_cstr("source.lang.swift.ref.var.instance")!
|
|
decl_var_static = api.uid_get_from_cstr("source.lang.swift.decl.var.static")!
|
|
ref_var_static = api.uid_get_from_cstr("source.lang.swift.ref.var.static")!
|
|
decl_var_class = api.uid_get_from_cstr("source.lang.swift.decl.var.class")!
|
|
ref_var_class = api.uid_get_from_cstr("source.lang.swift.ref.var.class")!
|
|
decl_var_local = api.uid_get_from_cstr("source.lang.swift.decl.var.local")!
|
|
ref_var_local = api.uid_get_from_cstr("source.lang.swift.ref.var.local")!
|
|
decl_var_parameter = api.uid_get_from_cstr("source.lang.swift.decl.var.parameter")!
|
|
decl_module = api.uid_get_from_cstr("source.lang.swift.decl.module")!
|
|
decl_class = api.uid_get_from_cstr("source.lang.swift.decl.class")!
|
|
ref_class = api.uid_get_from_cstr("source.lang.swift.ref.class")!
|
|
decl_struct = api.uid_get_from_cstr("source.lang.swift.decl.struct")!
|
|
ref_struct = api.uid_get_from_cstr("source.lang.swift.ref.struct")!
|
|
decl_enum = api.uid_get_from_cstr("source.lang.swift.decl.enum")!
|
|
ref_enum = api.uid_get_from_cstr("source.lang.swift.ref.enum")!
|
|
decl_enumcase = api.uid_get_from_cstr("source.lang.swift.decl.enumcase")!
|
|
decl_enumelement = api.uid_get_from_cstr("source.lang.swift.decl.enumelement")!
|
|
ref_enumelement = api.uid_get_from_cstr("source.lang.swift.ref.enumelement")!
|
|
decl_protocol = api.uid_get_from_cstr("source.lang.swift.decl.protocol")!
|
|
ref_protocol = api.uid_get_from_cstr("source.lang.swift.ref.protocol")!
|
|
decl_extension = api.uid_get_from_cstr("source.lang.swift.decl.extension")!
|
|
decl_extension_struct = api.uid_get_from_cstr("source.lang.swift.decl.extension.struct")!
|
|
decl_extension_class = api.uid_get_from_cstr("source.lang.swift.decl.extension.class")!
|
|
decl_extension_enum = api.uid_get_from_cstr("source.lang.swift.decl.extension.enum")!
|
|
decl_extension_protocol = api.uid_get_from_cstr("source.lang.swift.decl.extension.protocol")!
|
|
decl_associatedtype = api.uid_get_from_cstr("source.lang.swift.decl.associatedtype")!
|
|
ref_associatedtype = api.uid_get_from_cstr("source.lang.swift.ref.associatedtype")!
|
|
decl_typealias = api.uid_get_from_cstr("source.lang.swift.decl.typealias")!
|
|
ref_typealias = api.uid_get_from_cstr("source.lang.swift.ref.typealias")!
|
|
decl_generic_type_param = api.uid_get_from_cstr("source.lang.swift.decl.generic_type_param")!
|
|
ref_generic_type_param = api.uid_get_from_cstr("source.lang.swift.ref.generic_type_param")!
|
|
ref_module = api.uid_get_from_cstr("source.lang.swift.ref.module")!
|
|
syntaxtype_comment = api.uid_get_from_cstr("source.lang.swift.syntaxtype.comment")!
|
|
|
|
kind_keyword = api.uid_get_from_cstr("source.lang.swift.keyword")!
|
|
}
|
|
}
|
|
|
|
final class SKRequestDictionary {
|
|
let dict: sourcekitd_object_t?
|
|
let sourcekitd: SwiftSourceKitFramework
|
|
|
|
init(_ dict: sourcekitd_object_t? = nil, sourcekitd: SwiftSourceKitFramework) {
|
|
self.dict = dict ?? sourcekitd.api.request_dictionary_create(nil, nil, 0)
|
|
self.sourcekitd = sourcekitd
|
|
}
|
|
|
|
deinit {
|
|
sourcekitd.api.request_release(dict)
|
|
}
|
|
|
|
subscript(key: sourcekitd_uid_t?) -> String {
|
|
get { fatalError("request is set-only") }
|
|
set { sourcekitd.api.request_dictionary_set_string(dict, key, newValue) }
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> Int {
|
|
get { fatalError("request is set-only") }
|
|
set { sourcekitd.api.request_dictionary_set_int64(dict, key, Int64(newValue)) }
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> sourcekitd_uid_t? {
|
|
get { fatalError("request is set-only") }
|
|
set { sourcekitd.api.request_dictionary_set_uid(dict, key, newValue) }
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> SKRequestDictionary {
|
|
get { fatalError("request is set-only") }
|
|
set { sourcekitd.api.request_dictionary_set_value(dict, key, newValue.dict) }
|
|
}
|
|
subscript<S>(key: sourcekitd_uid_t?) -> S where S: Sequence, S.Element == String {
|
|
get { fatalError("request is set-only") }
|
|
set {
|
|
let array = SKRequestArray(sourcekitd: sourcekitd)
|
|
newValue.forEach { array.append($0) }
|
|
sourcekitd.api.request_dictionary_set_value(dict, key, array.array)
|
|
}
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> SKRequestArray {
|
|
get { fatalError("request is set-only") }
|
|
set { sourcekitd.api.request_dictionary_set_value(dict, key, newValue.array) }
|
|
}
|
|
}
|
|
|
|
final class SKRequestArray {
|
|
let array: sourcekitd_object_t?
|
|
let sourcekitd: SwiftSourceKitFramework
|
|
|
|
init(_ array: sourcekitd_object_t? = nil, sourcekitd: SwiftSourceKitFramework) {
|
|
self.array = array ?? sourcekitd.api.request_array_create(nil, 0)
|
|
self.sourcekitd = sourcekitd
|
|
}
|
|
|
|
deinit {
|
|
sourcekitd.api.request_release(array)
|
|
}
|
|
|
|
func append(_ value: String) {
|
|
sourcekitd.api.request_array_set_string(array, -1, value)
|
|
}
|
|
}
|
|
|
|
final class SKResponse {
|
|
let response: sourcekitd_response_t?
|
|
let sourcekitd: SwiftSourceKitFramework
|
|
|
|
init(_ response: sourcekitd_response_t?, sourcekitd: SwiftSourceKitFramework) {
|
|
self.response = response
|
|
self.sourcekitd = sourcekitd
|
|
}
|
|
|
|
deinit {
|
|
sourcekitd.api.response_dispose(response)
|
|
}
|
|
|
|
var error: ResponseError? {
|
|
if !sourcekitd.api.response_is_error(response) {
|
|
return nil
|
|
}
|
|
switch sourcekitd.api.response_error_get_kind(response) {
|
|
case SOURCEKITD_ERROR_REQUEST_CANCELLED:
|
|
return .cancelled
|
|
default:
|
|
return .unknown(description)
|
|
}
|
|
}
|
|
|
|
var value: SKResponseDictionary? {
|
|
if sourcekitd.api.response_is_error(response) {
|
|
return nil
|
|
}
|
|
return SKResponseDictionary(sourcekitd.api.response_get_value(response), response: self)
|
|
}
|
|
}
|
|
|
|
final class SKResponseDictionary {
|
|
let dict: sourcekitd_variant_t
|
|
let resp: SKResponse
|
|
var sourcekitd: SwiftSourceKitFramework { return resp.sourcekitd }
|
|
|
|
init(_ dict: sourcekitd_variant_t, response: SKResponse) {
|
|
self.dict = dict
|
|
self.resp = response
|
|
}
|
|
|
|
subscript(key: sourcekitd_uid_t?) -> String? {
|
|
return sourcekitd.api.variant_dictionary_get_string(dict, key).map(String.init(cString:))
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> Int? {
|
|
return Int(sourcekitd.api.variant_dictionary_get_int64(dict, key))
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> sourcekitd_uid_t? {
|
|
return sourcekitd.api.variant_dictionary_get_uid(dict, key)
|
|
}
|
|
subscript(key: sourcekitd_uid_t?) -> SKResponseArray? {
|
|
return SKResponseArray(sourcekitd.api.variant_dictionary_get_value(dict, key), response: resp)
|
|
}
|
|
}
|
|
|
|
final class SKResponseArray {
|
|
let array: sourcekitd_variant_t
|
|
let resp: SKResponse
|
|
var sourcekitd: SwiftSourceKitFramework { return resp.sourcekitd }
|
|
|
|
init(_ array: sourcekitd_variant_t, response: SKResponse) {
|
|
self.array = array
|
|
self.resp = response
|
|
}
|
|
|
|
var count: Int { return sourcekitd.api.variant_array_get_count(array) }
|
|
|
|
/// If the `applier` returns `false`, iteration terminates.
|
|
@discardableResult
|
|
func forEach(_ applier: (Int, SKResponseDictionary) -> Bool) -> Bool {
|
|
for i in 0..<count {
|
|
if !applier(i, SKResponseDictionary(sourcekitd.api.variant_array_get_value(array, i), response: resp)) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
extension SKRequestDictionary: CustomStringConvertible {
|
|
var description: String {
|
|
let ptr = sourcekitd.api.request_description_copy(dict)!
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|
|
|
|
extension SKRequestArray: CustomStringConvertible {
|
|
var description: String {
|
|
let ptr = sourcekitd.api.request_description_copy(array)!
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|
|
|
|
extension SKResponse: CustomStringConvertible {
|
|
var description: String {
|
|
let ptr = sourcekitd.api.response_description_copy(response)!
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|
|
|
|
extension SKResponseDictionary: CustomStringConvertible {
|
|
var description: String {
|
|
let ptr = sourcekitd.api.variant_description_copy(dict)!
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|
|
|
|
extension SKResponseArray: CustomStringConvertible {
|
|
var description: String {
|
|
let ptr = sourcekitd.api.variant_description_copy(array)!
|
|
defer { free(ptr) }
|
|
return String(cString: ptr)
|
|
}
|
|
}
|