Merge pull request #78421 from ahoppen/add-sourcekit-plugin

[SourceKit] Add mechanism to load plugins for request handling into SourceKit
This commit is contained in:
Alex Hoppen
2025-01-15 12:42:10 -08:00
committed by GitHub
43 changed files with 3756 additions and 431 deletions

View File

@@ -0,0 +1,23 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_BASIC_LOADDYNAMICLIBRARY_H
#define SWIFT_BASIC_LOADDYNAMICLIBRARY_H
#include <string>
namespace swift {
void *loadLibrary(const char *path, std::string *err);
void *getAddressOfSymbol(void *handle, const char *symbol);
} // end namespace swift
#endif // SWIFT_BASIC_LOADDYNAMICLIBRARY_H

View File

@@ -14,6 +14,7 @@
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Defer.h"
#include "swift/Basic/LoadDynamicLibrary.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Program.h"
#include "swift/Basic/Sandbox.h"
@@ -25,16 +26,6 @@
#include <signal.h>
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Windows/WindowsSupport.h"
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#elif defined(_WIN32)
@@ -43,46 +34,6 @@
using namespace swift;
namespace {
void *loadLibrary(const char *path, std::string *err);
void *getAddressOfSymbol(void *handle, const char *symbol);
#if defined(_WIN32)
void *loadLibrary(const char *path, std::string *err) {
SmallVector<wchar_t, MAX_PATH> pathUnicode;
if (std::error_code ec = llvm::sys::windows::UTF8ToUTF16(path, pathUnicode)) {
SetLastError(ec.value());
llvm::MakeErrMsg(err, std::string(path) + ": Can't convert to UTF-16");
return nullptr;
}
HMODULE handle = LoadLibraryW(pathUnicode.data());
if (handle == NULL) {
llvm::MakeErrMsg(err, std::string(path) + ": Can't open");
return nullptr;
}
return (void *)handle;
}
void *getAddressOfSymbol(void *handle, const char *symbol) {
return (void *)uintptr_t(GetProcAddress((HMODULE)handle, symbol));
}
#else
void *loadLibrary(const char *path, std::string *err) {
void *handle = ::dlopen(path, RTLD_LAZY | RTLD_LOCAL);
if (!handle)
*err = ::dlerror();
return handle;
}
void *getAddressOfSymbol(void *handle, const char *symbol) {
return ::dlsym(handle, symbol);
}
#endif
} // namespace
PluginRegistry::PluginRegistry() {
dumpMessaging = ::getenv("SWIFT_DUMP_PLUGIN_MESSAGING") != nullptr;
}

View File

@@ -58,6 +58,7 @@ add_swift_host_library(swiftBasic STATIC
ParseableOutput.cpp
JSONSerialization.cpp
LangOptions.cpp
LoadDynamicLibrary.cpp
Located.cpp
Mangler.cpp
OutputFileMap.cpp

View File

@@ -0,0 +1,58 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#include "swift/Basic/LoadDynamicLibrary.h"
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Windows/WindowsSupport.h"
#include "swift/Basic/LLVM.h"
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#if defined(_WIN32)
void *swift::loadLibrary(const char *path, std::string *err) {
SmallVector<wchar_t, MAX_PATH> pathUnicode;
if (std::error_code ec = llvm::sys::windows::UTF8ToUTF16(path, pathUnicode)) {
SetLastError(ec.value());
llvm::MakeErrMsg(err, std::string(path) + ": Can't convert to UTF-16");
return nullptr;
}
HMODULE handle = LoadLibraryW(pathUnicode.data());
if (handle == NULL) {
llvm::MakeErrMsg(err, std::string(path) + ": Can't open");
return nullptr;
}
return (void *)handle;
}
void *swift::getAddressOfSymbol(void *handle, const char *symbol) {
return (void *)uintptr_t(GetProcAddress((HMODULE)handle, symbol));
}
#else
void *swift::loadLibrary(const char *path, std::string *err) {
void *handle = ::dlopen(path, RTLD_LAZY | RTLD_LOCAL);
if (!handle)
*err = ::dlerror();
return handle;
}
void *swift::getAddressOfSymbol(void *handle, const char *symbol) {
return ::dlsym(handle, symbol);
}
#endif

View File

@@ -31,28 +31,30 @@ namespace llvm {
namespace SourceKit {
class LangSupport;
class NotificationCenter;
class PluginSupport;
class GlobalConfig {
public:
struct Settings {
struct IDEInspectionOptions {
class GlobalConfig {
public:
struct Settings {
struct IDEInspectionOptions {
/// Max count of reusing ASTContext for cached IDE inspection.
unsigned MaxASTContextReuseCount = 100;
/// Max count of reusing ASTContext for cached IDE inspection.
unsigned MaxASTContextReuseCount = 100;
/// Interval second for checking dependencies in cached IDE inspection.
unsigned CheckDependencyInterval = 5;
} IDEInspectionOpts;
};
/// Interval second for checking dependencies in cached IDE inspection.
unsigned CheckDependencyInterval = 5;
} IDEInspectionOpts;
};
private:
Settings State;
mutable llvm::sys::Mutex Mtx;
private:
Settings State;
mutable llvm::sys::Mutex Mtx;
public:
Settings update(std::optional<unsigned> IDEInspectionMaxASTContextReuseCount,
std::optional<unsigned> IDEInspectionCheckDependencyInterval);
Settings::IDEInspectionOptions getIDEInspectionOpts() const;
public:
Settings
update(std::optional<unsigned> IDEInspectionMaxASTContextReuseCount,
std::optional<unsigned> IDEInspectionCheckDependencyInterval);
Settings::IDEInspectionOptions getIDEInspectionOpts() const;
};
/// Keeps track of all requests that are currently in progress and coordinates
@@ -169,6 +171,7 @@ class Context {
std::shared_ptr<NotificationCenter> NotificationCtr;
std::shared_ptr<GlobalConfig> Config;
std::shared_ptr<RequestTracker> ReqTracker;
std::shared_ptr<PluginSupport> Plugins;
std::shared_ptr<SlowRequestSimulator> SlowRequestSim;
public:
@@ -176,6 +179,8 @@ public:
StringRef DiagnosticDocumentationPath,
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
LangSupportFactoryFn,
llvm::function_ref<std::shared_ptr<PluginSupport>(Context &)>
PluginSupportFactoryFn,
bool shouldDispatchNotificationsOnMain = true);
~Context();
@@ -192,6 +197,8 @@ public:
std::shared_ptr<GlobalConfig> getGlobalConfiguration() { return Config; }
std::shared_ptr<PluginSupport> getPlugins() { return Plugins; }
std::shared_ptr<SlowRequestSimulator> getSlowRequestSimulator() {
return SlowRequestSim;
}

View File

@@ -1024,6 +1024,8 @@ public:
virtual ~LangSupport() { }
virtual void *getOpaqueSwiftIDEInspectionInstance() { return nullptr; }
virtual void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) {};
virtual void dependencyUpdated() {}

View File

@@ -40,6 +40,8 @@ SourceKit::Context::Context(
StringRef DiagnosticDocumentationPath,
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
LangSupportFactoryFn,
llvm::function_ref<std::shared_ptr<PluginSupport>(Context &)>
PluginSupportFactoryFn,
bool shouldDispatchNotificationsOnMain)
: SwiftExecutablePath(SwiftExecutablePath), RuntimeLibPath(RuntimeLibPath),
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
@@ -49,6 +51,7 @@ SourceKit::Context::Context(
SlowRequestSim(new SlowRequestSimulator(ReqTracker)) {
// Should be called last after everything is initialized.
SwiftLang = LangSupportFactoryFn(*this);
Plugins = PluginSupportFactoryFn(*this);
}
SourceKit::Context::~Context() {

View File

@@ -534,6 +534,10 @@ public:
// LangSupport Interface
//==========================================================================//
void *getOpaqueSwiftIDEInspectionInstance() override {
return IDEInspectionInst.get();
}
void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) override;
void dependencyUpdated() override;

View File

@@ -11,6 +11,7 @@ swift_is_installing_component(sourcekit-inproc SOURCEKIT_INSTALLING_INPROC)
set(sourcekitdInProc_args
sourcekitdInProc.cpp
CodeCompletionSwiftInterop.cpp
LLVM_LINK_COMPONENTS support coverage
)
@@ -18,6 +19,8 @@ if (SOURCEKIT_INSTALLING_INPROC)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
add_sourcekit_framework(sourcekitdInProc
${SOURCEKITD_SOURCE_DIR}/include/sourcekitd/sourcekitd.h
${SOURCEKITD_SOURCE_DIR}/include/sourcekitd/plugin.h
${CMAKE_CURRENT_SOURCE_DIR}/CodeCompletionSwiftInterop.h
${sourcekitdInProc_args}
MODULEMAP module.modulemap
INSTALL_IN_COMPONENT sourcekit-inproc

View File

@@ -0,0 +1,905 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#include "CodeCompletionSwiftInterop.h"
#include "SourceKit/Core/Context.h"
#include "sourcekitd/sourcekitdInProc-Internal.h"
#include "swift/AST/ASTPrinter.h"
#include "swift/AST/USRGeneration.h"
#include "swift/Basic/StringExtras.h"
#include "swift/Driver/FrontendUtil.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/CodeCompletion.h"
#include "swift/IDE/CodeCompletionCache.h"
#include "swift/IDE/CodeCompletionResultPrinter.h"
#include "swift/IDE/FuzzyStringMatcher.h"
#include "swift/IDE/Utils.h"
#include "swift/IDETool/CompilerInvocation.h"
#include "swift/IDETool/IDEInspectionInstance.h"
#include "llvm/Support/Signals.h"
#include <mutex>
#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#else
#include <dlfcn.h>
#endif
using namespace swift;
using namespace swift::ide;
using namespace sourcekitdInProc;
static std::string getRuntimeResourcesPath();
using FileSystemRef = llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>;
namespace {
struct CompletionResult;
class SharedStringInMemoryFS : public llvm::vfs::InMemoryFileSystem {
SmallVector<std::shared_ptr<std::string>, 8> strings;
public:
SharedStringInMemoryFS(
const llvm::StringMap<std::shared_ptr<std::string>> &files) {
strings.reserve(files.size());
for (auto &pair : files) {
strings.push_back(pair.getValue());
auto buffer =
llvm::MemoryBuffer::getMemBuffer(*pair.getValue(), pair.getKey());
if (!addFile(pair.getKey(), /*ModTime=*/0, std::move(buffer))) {
// FIXME: report error!
}
}
}
};
class Connection {
IDEInspectionInstance *ideInspectionInstance;
/// If the connection was not passed an `IDEInspectionInstance` it creates
/// its own. This unique_ptr scopes the lifetime of 'ideInspectionInstance'
/// to the lifetime of 'Connection'.
std::unique_ptr<IDEInspectionInstance> ownedIDEInspectionInstance;
llvm::StringMap<std::shared_ptr<std::string>> modifiedFiles;
std::shared_ptr<CodeCompletionCache> completionCache;
std::string swiftExecutablePath;
std::string runtimeResourcePath;
std::string diagnosticsDocumentationPath;
std::shared_ptr<SourceKit::RequestTracker> requestTracker;
public:
std::unique_ptr<CompletionResult> currentResponse;
const time_t sessionTimestamp;
Connection(IDEInspectionInstance *ideInspectionInstance)
: ideInspectionInstance(ideInspectionInstance),
completionCache(std::make_shared<CodeCompletionCache>()),
swiftExecutablePath(getSwiftExecutablePath()),
runtimeResourcePath(getRuntimeResourcesPath()),
diagnosticsDocumentationPath(getDiagnosticDocumentationPath()),
requestTracker(new SourceKit::RequestTracker()),
sessionTimestamp(llvm::sys::toTimeT(std::chrono::system_clock::now())) {
if (ideInspectionInstance == nullptr) {
this->ownedIDEInspectionInstance.reset(new IDEInspectionInstance());
this->ideInspectionInstance = this->ownedIDEInspectionInstance.get();
}
}
void setFileContents(StringRef path, const char *contents) {
if (contents) {
modifiedFiles[path] = std::make_shared<std::string>(contents);
} else {
modifiedFiles.erase(path);
}
}
std::shared_ptr<CodeCompletionCache> getCompletionCache() const {
return completionCache;
}
FileSystemRef createFileSystem() {
auto *overlayFS =
new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem());
overlayFS->pushOverlay(new SharedStringInMemoryFS(modifiedFiles));
return overlayFS;
}
void cancelRequest(SourceKit::SourceKitCancellationToken cancellationToken) {
requestTracker->cancel(cancellationToken);
}
void codeComplete(
StringRef path, unsigned offset, ArrayRef<const char *> args,
FileSystemRef fileSystem, ide::CodeCompletionContext &completionContext,
SourceKit::SourceKitCancellationToken cancellationToken,
llvm::function_ref<void(CancellableResult<CodeCompleteResult>)> callback);
void markCachedCompilerInstanceShouldBeInvalidated() {
ideInspectionInstance->markCachedCompilerInstanceShouldBeInvalidated();
}
};
} // anonymous namespace
swiftide_connection_t swiftide_connection_create(void) {
return swiftide_connection_create_with_inspection_instance(nullptr);
}
swiftide_connection_t swiftide_connection_create_with_inspection_instance(
void *opaqueIDESwiftInspectionInstance) {
static std::once_flag once;
std::call_once(
once, [] { llvm::sys::PrintStackTraceOnErrorSignal("IDESwiftInterop"); });
IDEInspectionInstance *inspectInstance =
static_cast<IDEInspectionInstance *>(opaqueIDESwiftInspectionInstance);
return static_cast<swiftide_connection_t>(new Connection(inspectInstance));
}
void swiftide_connection_dispose(swiftide_connection_t conn) {
assert(conn);
delete static_cast<Connection *>(conn);
}
void swiftide_connection_mark_cached_compiler_instance_should_be_invalidated(
swiftide_connection_t _conn, swiftide_cache_invalidation_options_t _opts) {
auto *conn = static_cast<Connection *>(_conn);
// '_opts' is not used at this point.
assert(conn);
conn->markCachedCompilerInstanceShouldBeInvalidated();
}
void swiftide_set_file_contents(swiftide_connection_t _conn, const char *path,
const char *contents) {
auto *conn = static_cast<Connection *>(_conn);
assert(conn);
conn->setFileContents(path, contents);
}
namespace {
struct CompletionResult {
Connection &conn;
CodeCompletionContext context;
ImportDepth importDepth;
std::string error;
bool isCancelled = false;
SmallString<0> scratch;
CodeCompletionResultSink resultSink;
/// The compiler instance that produced the results. Used to lazily compute
/// diagnostics for results.
std::shared_ptr<CompilerInstance> compilerInstance;
CompletionResult(Connection &conn)
: conn(conn), context(*conn.getCompletionCache()) {
// Pre-allocate a whole page. Empirically, this is enough to cover the vast
// majority of cases.
scratch.reserve(4096);
}
bool hasError() const { return !error.empty(); }
ArrayRef<CodeCompletionResult *> getCompletions() {
return resultSink.Results;
}
};
struct SwiftInteropCodeCompletionConsumer : public ide::CodeCompletionConsumer {
CompletionResult &result;
SwiftInteropCodeCompletionConsumer(CompletionResult &result)
: result(result) {}
void handleResults(CodeCompletionContext &context) override {
assert(&context == &(result.context));
}
};
struct CompletionRequest {
llvm::BumpPtrAllocator allocator;
StringRef path;
unsigned offset;
std::vector<const char *> compilerArguments;
bool annotateResult = false;
bool includeObjectLiterals = true;
bool addInitsToTopLevel = false;
bool addCallWithNoDefaultArgs = true;
CompletionRequest(const char *path, unsigned offset,
ArrayRef<const char *> args) {
this->path = StringRef(path).copy(allocator);
this->offset = offset;
compilerArguments.reserve(args.size());
for (const char *arg : args) {
compilerArguments.push_back(copyCString(arg, allocator));
}
}
};
} // namespace
void swiftide_cancel_request(swiftide_connection_t _conn,
swiftide_request_handle_t handle) {
assert(_conn);
auto *conn = static_cast<Connection *>(_conn);
conn->cancelRequest(handle);
}
swiftide_completion_request_t
swiftide_completion_request_create(const char *path, uint32_t offset,
char *const *const compiler_args,
uint32_t num_compiler_args) {
return new CompletionRequest(
path, offset, llvm::ArrayRef(compiler_args, num_compiler_args));
}
void swiftide_completion_request_dispose(swiftide_completion_request_t _req) {
delete static_cast<CompletionRequest *>(_req);
}
void swiftide_completion_request_set_annotate_result(
swiftide_completion_request_t _req, bool annotate) {
auto &req = *static_cast<CompletionRequest *>(_req);
req.annotateResult = annotate;
}
void swiftide_completion_request_set_include_objectliterals(
swiftide_completion_request_t _req, bool flag) {
auto &req = *static_cast<CompletionRequest *>(_req);
req.includeObjectLiterals = flag;
}
void swiftide_completion_request_set_add_inits_to_top_level(
swiftide_completion_request_t _req, bool flag) {
auto &req = *static_cast<CompletionRequest *>(_req);
req.addInitsToTopLevel = flag;
}
void swiftide_completion_request_set_add_call_with_no_default_args(
swiftide_completion_request_t _req, bool flag) {
auto &req = *static_cast<CompletionRequest *>(_req);
req.addCallWithNoDefaultArgs = flag;
}
swiftide_completion_response_t
swiftide_complete_cancellable(swiftide_connection_t _conn,
swiftide_completion_request_t _req,
swiftide_request_handle_t handle) {
assert(_conn && _req);
auto *conn = static_cast<Connection *>(_conn);
auto &req = *static_cast<CompletionRequest *>(_req);
if (conn->currentResponse) {
llvm::report_fatal_error(
"must dispose of previous response before completing again");
}
conn->currentResponse = std::make_unique<CompletionResult>(*conn);
auto result = conn->currentResponse.get();
SwiftInteropCodeCompletionConsumer consumer(*result);
auto fileSystem = conn->createFileSystem();
result->context.setAnnotateResult(req.annotateResult);
result->context.setIncludeObjectLiterals(req.includeObjectLiterals);
result->context.setAddInitsToTopLevel(req.addInitsToTopLevel);
result->context.setAddCallWithNoDefaultArgs(req.addCallWithNoDefaultArgs);
conn->codeComplete(
req.path, req.offset, req.compilerArguments, fileSystem, result->context,
handle, [&result](CancellableResult<CodeCompleteResult> completeResult) {
switch (completeResult.getKind()) {
case CancellableResultKind::Success:
result->importDepth = completeResult->ImportDep;
result->resultSink = completeResult->ResultSink;
result->compilerInstance = completeResult->Info.compilerInstance;
break;
case CancellableResultKind::Failure:
result->error = completeResult.getError();
break;
case CancellableResultKind::Cancelled:
result->isCancelled = true;
break;
}
});
return static_cast<swiftide_completion_response_t>(result);
}
swiftide_completion_response_t
swiftide_complete(swiftide_connection_t _conn,
swiftide_completion_request_t _req) {
// handle = nullptr indicates that the request can't be cancelled.
return swiftide_complete_cancellable(_conn, _req, /*handle=*/nullptr);
}
void Connection::codeComplete(
StringRef path, unsigned offset, ArrayRef<const char *> args,
FileSystemRef fileSystem, ide::CodeCompletionContext &completionContext,
SourceKit::SourceKitCancellationToken cancellationToken,
llvm::function_ref<void(CancellableResult<CodeCompleteResult>)> callback) {
using ResultType = CancellableResult<CodeCompleteResult>;
// Resolve symlinks for the input file; we resolve them for the input files
// in the arguments as well.
// FIXME: We need the Swift equivalent of Clang's FileEntry.
llvm::SmallString<128> bufferIdentifier;
if (auto err = fileSystem->getRealPath(path, bufferIdentifier))
bufferIdentifier = path;
auto inputFile = fileSystem->openFileForRead(path);
if (auto err = inputFile.getError()) {
std::string error;
llvm::raw_string_ostream OS(error);
OS << "failed to open '" << path << "': " << err.message();
callback(ResultType::failure(error));
return;
}
auto inputBuffer = inputFile->get()->getBuffer(bufferIdentifier);
if (auto err = inputBuffer.getError()) {
std::string error;
llvm::raw_string_ostream OS(error);
OS << "failed to read '" << path << "': " << err.message();
callback(ResultType::failure(error));
return;
}
// Create a buffer for code completion. This contains '\0' at 'Offset'
// position of 'UnresolvedInputFile' buffer.
auto newBuffer = ide::makeCodeCompletionMemoryBuffer(
inputBuffer.get().get(), offset, bufferIdentifier);
CompilerInvocation invocation;
SourceManager SM;
DiagnosticEngine diags(SM);
ForwardingDiagnosticConsumer ciDiags(diags);
PrintingDiagnosticConsumer printDiags;
diags.addConsumer(printDiags);
std::string compilerInvocationError;
bool creatingInvocationFailed = initCompilerInvocation(
invocation, args, FrontendOptions::ActionType::Typecheck, diags, path,
fileSystem, swiftExecutablePath, runtimeResourcePath,
diagnosticsDocumentationPath, sessionTimestamp, compilerInvocationError);
if (creatingInvocationFailed) {
callback(ResultType::failure(compilerInvocationError));
return;
} else if (!invocation.getFrontendOptions().InputsAndOutputs.hasInputs()) {
callback(ResultType::failure("no input filenames specified"));
return;
}
auto cancellationFlag = std::make_shared<std::atomic<bool>>(false);
requestTracker->setCancellationHandler(
cancellationToken, [cancellationFlag]() {
cancellationFlag->store(true, std::memory_order_relaxed);
});
ideInspectionInstance->codeComplete(
invocation, args, fileSystem, newBuffer.get(), offset, &ciDiags,
completionContext, cancellationFlag, callback);
}
void swiftide_completion_result_dispose(swiftide_completion_response_t result) {
auto *response = static_cast<CompletionResult *>(result);
auto &conn = response->conn;
assert(conn.currentResponse.get() == response);
conn.currentResponse = nullptr;
}
bool swiftide_completion_result_is_error(
swiftide_completion_response_t _result) {
auto &result = *static_cast<CompletionResult *>(_result);
return result.hasError();
}
const char *swiftide_completion_result_get_error_description(
swiftide_completion_response_t _result) {
auto &result = *static_cast<CompletionResult *>(_result);
return result.error.c_str();
}
bool swiftide_completion_result_is_cancelled(
swiftide_completion_response_t _result) {
auto result = static_cast<CompletionResult *>(_result);
return result->isCancelled;
}
/// Copies a string representation of the completion result. This string should
/// be disposed of with \c free when done.
const char *swiftide_completion_result_description_copy(
swiftide_completion_response_t _result) {
auto &result = *static_cast<CompletionResult *>(_result);
std::string desc;
do {
llvm::raw_string_ostream OS(desc);
if (result.hasError()) {
OS << "error: " << result.error;
break;
}
/// FXIME: this code copied from PrintingCodeCompletionConsumer
OS << "Begin completions, " << result.getCompletions().size() << " items\n";
for (auto *item : result.getCompletions()) {
item->printPrefix(OS);
if (result.context.getAnnotateResult()) {
printCodeCompletionResultDescriptionAnnotated(
*item, OS, /*leadingPunctuation=*/false);
OS << "; typename=";
printCodeCompletionResultTypeNameAnnotated(*item, OS);
} else {
item->getCompletionString()->print(OS);
}
OS << "; name=" << item->getFilterName();
OS << "\n";
}
OS << "End completions\n";
} while (0);
return strdup(desc.c_str());
}
void swiftide_completion_result_get_completions(
swiftide_completion_response_t _result,
void (^completions_handler)(const swiftide_completion_item_t *completions,
const char **filter_names,
uint64_t num_completions)) {
auto &result = *static_cast<CompletionResult *>(_result);
if (result.hasError() || result.getCompletions().empty()) {
completions_handler(nullptr, nullptr, 0);
return;
}
std::vector<const char *> filterNames;
filterNames.reserve(result.getCompletions().size());
for (auto *item : result.getCompletions()) {
filterNames.push_back(item->getFilterName().data());
}
assert(filterNames.size() == result.getCompletions().size());
completions_handler(
(const swiftide_completion_item_t *)result.getCompletions().data(),
filterNames.data(), result.getCompletions().size());
}
swiftide_completion_item_t swiftide_completion_result_get_completion_at_index(
swiftide_completion_response_t _response, uint64_t index) {
auto &response = *static_cast<CompletionResult *>(_response);
if (response.hasError() || response.getCompletions().size() < index) {
return nullptr;
}
return response.getCompletions()[index];
}
swiftide_completion_kind_t
swiftide_completion_result_get_kind(swiftide_completion_response_t _response) {
auto &response = *static_cast<CompletionResult *>(_response);
switch (response.context.CodeCompletionKind) {
case CompletionKind::None:
return SWIFTIDE_COMPLETION_KIND_NONE;
case CompletionKind::Import:
return SWIFTIDE_COMPLETION_KIND_IMPORT;
case CompletionKind::UnresolvedMember:
return SWIFTIDE_COMPLETION_KIND_UNRESOLVEDMEMBER;
case CompletionKind::DotExpr:
return SWIFTIDE_COMPLETION_KIND_DOTEXPR;
case CompletionKind::StmtOrExpr:
return SWIFTIDE_COMPLETION_KIND_STMTOREXPR;
case CompletionKind::PostfixExprBeginning:
return SWIFTIDE_COMPLETION_KIND_POSTFIXEXPRBEGINNING;
case CompletionKind::PostfixExpr:
return SWIFTIDE_COMPLETION_KIND_POSTFIXEXPR;
case CompletionKind::KeyPathExprObjC:
return SWIFTIDE_COMPLETION_KIND_KEYPATHEXPROBJC;
case CompletionKind::KeyPathExprSwift:
return SWIFTIDE_COMPLETION_KIND_KEYPATHEXPRSWIFT;
case CompletionKind::TypePossibleFunctionParamBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPEPOSSIBLEFUNCTIONPARAMBEGINNING;
case CompletionKind::TypeDeclResultBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPEDECLRESULTBEGINNING;
case CompletionKind::TypeBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPEBEGINNING;
case CompletionKind::TypeSimpleOrComposition:
return SWIFTIDE_COMPLETION_KIND_TYPESIMPLEORCOMPOSITION;
case CompletionKind::TypeSimpleBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPESIMPLEBEGINNING;
case CompletionKind::TypeSimpleWithDot:
// TODO: check if this is still correct
return SWIFTIDE_COMPLETION_KIND_TYPEIDENTIFIERWITHDOT;
case CompletionKind::TypeSimpleWithoutDot:
// TODO: check if this is still correct
return SWIFTIDE_COMPLETION_KIND_TYPEIDENTIFIERWITHOUTDOT;
case CompletionKind::CaseStmtKeyword:
return SWIFTIDE_COMPLETION_KIND_CASESTMTKEYWORD;
case CompletionKind::CaseStmtBeginning:
return SWIFTIDE_COMPLETION_KIND_CASESTMTBEGINNING;
case CompletionKind::NominalMemberBeginning:
return SWIFTIDE_COMPLETION_KIND_NOMINALMEMBERBEGINNING;
case CompletionKind::AccessorBeginning:
return SWIFTIDE_COMPLETION_KIND_ACCESSORBEGINNING;
case CompletionKind::AttributeBegin:
return SWIFTIDE_COMPLETION_KIND_ATTRIBUTEBEGIN;
case CompletionKind::AttributeDeclParen:
return SWIFTIDE_COMPLETION_KIND_ATTRIBUTEDECLPAREN;
case CompletionKind::EffectsSpecifier:
return SWIFTIDE_COMPLETION_KIND_EFFECTSSPECIFIER;
case CompletionKind::PoundAvailablePlatform:
return SWIFTIDE_COMPLETION_KIND_POUNDAVAILABLEPLATFORM;
case CompletionKind::CallArg:
return SWIFTIDE_COMPLETION_KIND_CALLARG;
case CompletionKind::ReturnStmtExpr:
return SWIFTIDE_COMPLETION_KIND_RETURNSTMTEXPR;
case CompletionKind::YieldStmtExpr:
return SWIFTIDE_COMPLETION_KIND_YIELDSTMTEXPR;
case CompletionKind::ForEachSequence:
return SWIFTIDE_COMPLETION_KIND_FOREACHSEQUENCE;
case CompletionKind::ForEachInKw:
return SWIFTIDE_COMPLETION_KIND_FOREACHKWIN;
case CompletionKind::AfterPoundExpr:
return SWIFTIDE_COMPLETION_KIND_AFTERPOUNDEXPR;
case CompletionKind::AfterPoundDirective:
return SWIFTIDE_COMPLETION_KIND_AFTERPOUNDDIRECTIVE;
case CompletionKind::PlatformConditon:
return SWIFTIDE_COMPLETION_KIND_PLATFORMCONDITON;
case CompletionKind::AfterIfStmtElse:
return SWIFTIDE_COMPLETION_KIND_AFTERIFSTMTELSE;
case CompletionKind::GenericRequirement:
return SWIFTIDE_COMPLETION_KIND_GENERICREQUIREMENT;
case CompletionKind::PrecedenceGroup:
return SWIFTIDE_COMPLETION_KIND_PRECEDENCEGROUP;
case CompletionKind::StmtLabel:
return SWIFTIDE_COMPLETION_KIND_STMTLABEL;
case CompletionKind::ForEachPatternBeginning:
return SWIFTIDE_COMPLETION_KIND_FOREACHPATTERNBEGINNING;
case CompletionKind::TypeAttrBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPEATTRBEGINNING;
case CompletionKind::TypeAttrInheritanceBeginning:
return SWIFTIDE_COMPLETION_KIND_TYPEATTRINHERITANCEBEGINNING;
case CompletionKind::OptionalBinding:
return SWIFTIDE_COMPLETION_KIND_OPTIONALBINDING;
case CompletionKind::TypeSimpleInverted:
return SWIFTIDE_COMPLETION_KIND_TYPESIMPLEINVERTED;
case CompletionKind::ThenStmtExpr:
return SWIFTIDE_COMPLETION_KIND_THENSTMTEXPR;
}
}
void swiftide_completion_result_foreach_baseexpr_typename(
swiftide_completion_response_t _response, bool (^handler)(const char *)) {
auto &response = *static_cast<CompletionResult *>(_response);
for (const auto typeName : response.context.LookedupNominalTypeNames) {
if (/*shouldStop=*/handler(typeName.data())) {
return;
}
}
}
bool swiftide_completion_result_is_reusing_astcontext(
swiftide_completion_response_t _response) {
auto &response = *static_cast<CompletionResult *>(_response);
return response.context.ReusingASTContext;
}
const char *
swiftide_completion_item_description_copy(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
llvm::SmallString<256> buffer;
{
llvm::raw_svector_ostream OS(buffer);
item.printPrefix(OS);
item.getCompletionString()->print(OS);
}
return strdup(buffer.c_str());
}
void swiftide_completion_item_get_label(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
bool annotate, void (^handler)(const char *)) {
auto &response = *static_cast<CompletionResult *>(_response);
auto &item = *static_cast<CodeCompletionResult *>(_item);
response.scratch.clear();
{
llvm::raw_svector_ostream OS(response.scratch);
if (annotate) {
printCodeCompletionResultDescriptionAnnotated(item, OS, false);
} else {
printCodeCompletionResultDescription(item, OS, false);
}
}
handler(response.scratch.c_str());
}
void swiftide_completion_item_get_source_text(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(const char *)) {
auto &response = *static_cast<CompletionResult *>(_response);
auto &item = *static_cast<CodeCompletionResult *>(_item);
response.scratch.clear();
{
llvm::raw_svector_ostream OS(response.scratch);
printCodeCompletionResultSourceText(item, OS);
}
handler(response.scratch.c_str());
}
void swiftide_completion_item_get_type_name(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
bool annotate, void (^handler)(const char *)) {
auto &response = *static_cast<CompletionResult *>(_response);
auto &item = *static_cast<CodeCompletionResult *>(_item);
response.scratch.clear();
{
llvm::raw_svector_ostream OS(response.scratch);
if (annotate) {
printCodeCompletionResultTypeNameAnnotated(item, OS);
} else {
printCodeCompletionResultTypeName(item, OS);
}
}
handler(response.scratch.empty() ? nullptr : response.scratch.c_str());
}
void swiftide_completion_item_get_doc_brief(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(const char *)) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
if (item.getBriefDocComment().empty()) {
return handler(nullptr);
}
handler(item.getBriefDocComment().data());
}
void swiftide_completion_item_get_associated_usrs(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(const char **, uint64_t)) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
llvm::SmallVector<const char *, 4> usrs;
for (auto usr : item.getAssociatedUSRs()) {
usrs.push_back(usr.data());
}
handler(usrs.data(), usrs.size());
}
uint32_t swiftide_completion_item_get_kind(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
// FIXME: keep this in sync with ide::CodeCompletionResult
return static_cast<swiftide_completion_item_kind_t>(item.getKind());
}
uint32_t
swiftide_completion_item_get_associated_kind(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
// FIXME: keep this in sync with ide::CodeCompletionResult
switch (item.getKind()) {
case CodeCompletionResultKind::Declaration:
switch (item.getAssociatedDeclKind()) {
#define CASE(KIND, VAL) \
case swift::ide::CodeCompletionDeclKind::KIND: \
return SWIFTIDE_COMPLETION_ITEM_DECL_KIND_##VAL;
CASE(Module, MODULE)
CASE(Class, CLASS)
CASE(Actor, ACTOR)
CASE(Struct, STRUCT)
CASE(Enum, ENUM)
CASE(EnumElement, ENUMELEMENT)
CASE(Protocol, PROTOCOL)
CASE(AssociatedType, ASSOCIATEDTYPE)
CASE(TypeAlias, TYPEALIAS)
CASE(GenericTypeParam, GENERICTYPEPARAM)
CASE(Constructor, CONSTRUCTOR)
CASE(Destructor, DESTRUCTOR)
CASE(Subscript, SUBSCRIPT)
CASE(StaticMethod, STATICMETHOD)
CASE(InstanceMethod, INSTANCEMETHOD)
CASE(PrefixOperatorFunction, PREFIXOPERATORFUNCTION)
CASE(PostfixOperatorFunction, POSTFIXOPERATORFUNCTION)
CASE(InfixOperatorFunction, INFIXOPERATORFUNCTION)
CASE(FreeFunction, FREEFUNCTION)
CASE(StaticVar, STATICVAR)
CASE(InstanceVar, INSTANCEVAR)
CASE(LocalVar, LOCALVAR)
CASE(GlobalVar, GLOBALVAR)
CASE(PrecedenceGroup, PRECEDENCEGROUP)
CASE(Macro, MACRO)
#undef CASE
}
llvm_unreachable("unhandled enum value");
case CodeCompletionResultKind::Literal:
return static_cast<uint32_t>(item.getLiteralKind());
case CodeCompletionResultKind::Keyword:
return static_cast<uint32_t>(item.getKeywordKind());
default:
return 0;
}
}
uint32_t swiftide_completion_item_get_semantic_context(
swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
switch (item.getSemanticContext()) {
case swift::ide::SemanticContextKind::None:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_NONE;
case swift::ide::SemanticContextKind::Local:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_LOCAL;
case swift::ide::SemanticContextKind::CurrentNominal:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_CURRENTNOMINAL;
case swift::ide::SemanticContextKind::Super:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_SUPER;
case swift::ide::SemanticContextKind::OutsideNominal:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_OUTSIDENOMINAL;
case swift::ide::SemanticContextKind::CurrentModule:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_CURRENTMODULE;
case swift::ide::SemanticContextKind::OtherModule:
return SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_OTHERMODULE;
}
}
uint32_t swiftide_completion_item_get_flair(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
uint32_t result = 0;
auto flair = item.getFlair();
if (flair.contains(CodeCompletionFlairBit::ExpressionSpecific))
result |= SWIFTIDE_COMPLETION_FLAIR_EXPRESSIONSPECIFIC;
if (flair.contains(CodeCompletionFlairBit::SuperChain))
result |= SWIFTIDE_COMPLETION_FLAIR_SUPERCHAIN;
if (flair.contains(CodeCompletionFlairBit::ArgumentLabels))
result |= SWIFTIDE_COMPLETION_FLAIR_ARGUMENTLABELS;
if (flair.contains(CodeCompletionFlairBit::CommonKeywordAtCurrentPosition))
result |= SWIFTIDE_COMPLETION_FLAIR_COMMONKEYWORDATCURRENTPOSITION;
if (flair.contains(CodeCompletionFlairBit::RareKeywordAtCurrentPosition))
result |= SWIFTIDE_COMPLETION_FLAIR_RAREKEYWORDATCURRENTPOSITION;
if (flair.contains(CodeCompletionFlairBit::RareTypeAtCurrentPosition))
result |= SWIFTIDE_COMPLETION_FLAIR_RARETYPEATCURRENTPOSITION;
if (flair.contains(
CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope))
result |= SWIFTIDE_COMPLETION_FLAIR_EXPRESSIONATNONSCRIPTORMAINFILESCOPE;
return result;
}
bool swiftide_completion_item_is_not_recommended(
swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
return item.isNotRecommended();
}
uint32_t swiftide_completion_item_not_recommended_reason(
swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
switch (item.getNotRecommendedReason()) {
case NotRecommendedReason::None:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_NONE;
case NotRecommendedReason::RedundantImport:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_REDUNDANT_IMPORT;
case NotRecommendedReason::RedundantImportIndirect:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_REDUNDANT_IMPORT_INDIRECT;
case NotRecommendedReason::Deprecated:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_DEPRECATED;
case NotRecommendedReason::SoftDeprecated:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_SOFTDEPRECATED;
case NotRecommendedReason::VariableUsedInOwnDefinition:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_VARIABLE_USED_IN_OWN_DEFINITION;
case NotRecommendedReason::NonAsyncAlternativeUsedInAsyncContext:
return SWIFTIDE_COMPLETION_NOT_RECOMMENDED_NON_ASYNC_ALTERNATIVE_USED_IN_ASYNC_CONTEXT;
}
}
bool swiftide_completion_item_has_diagnostic(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
return (item.getNotRecommendedReason() != NotRecommendedReason::None);
}
void swiftide_completion_item_get_diagnostic(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(swiftide_completion_diagnostic_severity_t, const char *)) {
auto &response = *static_cast<CompletionResult *>(_response);
auto &item = *static_cast<CodeCompletionResult *>(_item);
swiftide_completion_diagnostic_severity_t severity;
llvm::SmallString<64> scratch;
auto severityAndMessage = item.getDiagnosticSeverityAndMessage(
scratch, response.compilerInstance->getASTContext());
switch (severityAndMessage.first) {
case CodeCompletionDiagnosticSeverity::None:
handler(SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_NONE, nullptr);
return;
case CodeCompletionDiagnosticSeverity::Error:
severity = SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_ERROR;
break;
case CodeCompletionDiagnosticSeverity::Warning:
severity = SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_WARNING;
break;
case CodeCompletionDiagnosticSeverity::Remark:
severity = SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_REMARK;
break;
case CodeCompletionDiagnosticSeverity::Note:
severity = SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_NOTE;
break;
}
handler(severity, severityAndMessage.second.data());
}
bool swiftide_completion_item_is_system(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
return item.isSystem();
}
void swiftide_completion_item_get_module_name(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(const char *)) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
handler(item.getContextFreeResult().getModuleName().data());
}
uint32_t swiftide_completion_item_get_num_bytes_to_erase(
swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
return item.getNumBytesToErase();
}
uint32_t
swiftide_completion_item_get_type_relation(swiftide_completion_item_t _item) {
auto &item = *static_cast<CodeCompletionResult *>(_item);
// FIXME: keep this in sync with ide::CodeCompletionResult
return static_cast<swiftide_completion_type_relation_t>(
item.getExpectedTypeRelation());
}
uint32_t
swiftide_completion_item_import_depth(swiftide_completion_response_t _response,
swiftide_completion_item_t _item) {
auto &response = *static_cast<CompletionResult *>(_response);
auto &item = *static_cast<CodeCompletionResult *>(_item);
if (item.getSemanticContext() == SemanticContextKind::OtherModule) {
if (auto depth = response.importDepth.lookup(item.getModuleName())) {
return *depth;
} else {
return ~0u;
}
} else {
return 0;
}
}
swiftide_fuzzy_match_pattern_t
swiftide_fuzzy_match_pattern_create(const char *pattern) {
return static_cast<swiftide_fuzzy_match_pattern_t>(
new FuzzyStringMatcher(pattern));
}
bool swiftide_fuzzy_match_pattern_matches_candidate(
swiftide_fuzzy_match_pattern_t _pattern, const char *_candidate,
double *outScore) {
auto &matcher = *static_cast<FuzzyStringMatcher *>(_pattern);
StringRef candidate = _candidate;
if (matcher.matchesCandidate(candidate)) {
if (outScore)
*outScore = matcher.scoreCandidate(candidate);
return true;
}
return false;
}
void swiftide_fuzzy_match_pattern_dispose(
swiftide_fuzzy_match_pattern_t _pattern) {
delete static_cast<FuzzyStringMatcher *>(_pattern);
}
static std::string getRuntimeResourcesPath() {
auto libPath = getRuntimeLibPath();
llvm::SmallString<128> libPathTmp(libPath);
llvm::sys::path::append(libPathTmp, "swift");
return libPathTmp.str().str();
}

View File

@@ -0,0 +1,408 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_C_CODE_COMPLETION_H
#define SWIFT_C_CODE_COMPLETION_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/// The version constants for the SwiftCodeCompletion C API.
/// SWIFTIDE_VERSION_MINOR should increase when there are API additions.
/// SWIFTIDE_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
#define SWIFTIDE_VERSION_MAJOR 0
#define SWIFTIDE_VERSION_MINOR 1
#define SWIFTIDE_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1))
#define SWIFTIDE_VERSION \
SWIFTIDE_VERSION_ENCODE(SWIFTIDE_VERSION_MAJOR, SWIFTIDE_VERSION_MINOR)
#define SWIFTIDE_VERSION_STRINGIZE_(major, minor) #major "." #minor
#define SWIFTIDE_VERSION_STRINGIZE(major, minor) \
SWIFTIDE_VERSION_STRINGIZE_(major, minor)
#define SWIFTIDE_VERSION_STRING \
SWIFTIDE_VERSION_STRINGIZE(SWIFTIDE_VERSION_MAJOR, SWIFTIDE_VERSION_MINOR)
#ifdef __cplusplus
#define SWIFTIDE_BEGIN_DECLS extern "C" {
#define SWIFTIDE_END_DECLS }
#else
#define SWIFTIDE_BEGIN_DECLS
#define SWIFTIDE_END_DECLS
#endif
#ifndef SWIFTIDE_PUBLIC
#if defined(_MSC_VER)
#define SWIFTIDE_PUBLIC __declspec(dllimport)
#else
#define SWIFTIDE_PUBLIC
#endif
#endif
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if !__has_feature(blocks)
#error -fblocks is a requirement to use this library
#endif
#if defined(__clang__) || defined(__GNUC__)
#define SWIFTIDE_DEPRECATED(m) __attribute__((deprecated(m)))
#endif
SWIFTIDE_BEGIN_DECLS
//=== Types ---------------------------------------------------------------===//
/// Global state across completions including compiler instance caching.
typedef void *swiftide_connection_t;
/// Opaque completion item handle, used to retrieve additional information that
/// may be more expensive to compute.
typedef void *swiftide_completion_item_t;
typedef enum {
SWIFTIDE_COMPLETION_KIND_NONE = 0,
SWIFTIDE_COMPLETION_KIND_IMPORT = 1,
SWIFTIDE_COMPLETION_KIND_UNRESOLVEDMEMBER = 2,
SWIFTIDE_COMPLETION_KIND_DOTEXPR = 3,
SWIFTIDE_COMPLETION_KIND_STMTOREXPR = 4,
SWIFTIDE_COMPLETION_KIND_POSTFIXEXPRBEGINNING = 5,
SWIFTIDE_COMPLETION_KIND_POSTFIXEXPR = 6,
/* obsoleted */ SWIFTIDE_COMPLETION_KIND_POSTFIXEXPRPAREN = 7,
SWIFTIDE_COMPLETION_KIND_KEYPATHEXPROBJC = 8,
SWIFTIDE_COMPLETION_KIND_KEYPATHEXPRSWIFT = 9,
SWIFTIDE_COMPLETION_KIND_TYPEDECLRESULTBEGINNING = 10,
SWIFTIDE_COMPLETION_KIND_TYPESIMPLEBEGINNING = 11,
SWIFTIDE_COMPLETION_KIND_TYPEIDENTIFIERWITHDOT = 12,
SWIFTIDE_COMPLETION_KIND_TYPEIDENTIFIERWITHOUTDOT = 13,
SWIFTIDE_COMPLETION_KIND_CASESTMTKEYWORD = 14,
SWIFTIDE_COMPLETION_KIND_CASESTMTBEGINNING = 15,
SWIFTIDE_COMPLETION_KIND_NOMINALMEMBERBEGINNING = 16,
SWIFTIDE_COMPLETION_KIND_ACCESSORBEGINNING = 17,
SWIFTIDE_COMPLETION_KIND_ATTRIBUTEBEGIN = 18,
SWIFTIDE_COMPLETION_KIND_ATTRIBUTEDECLPAREN = 19,
SWIFTIDE_COMPLETION_KIND_POUNDAVAILABLEPLATFORM = 20,
SWIFTIDE_COMPLETION_KIND_CALLARG = 21,
SWIFTIDE_COMPLETION_KIND_LABELEDTRAILINGCLOSURE = 22,
SWIFTIDE_COMPLETION_KIND_RETURNSTMTEXPR = 23,
SWIFTIDE_COMPLETION_KIND_YIELDSTMTEXPR = 24,
SWIFTIDE_COMPLETION_KIND_FOREACHSEQUENCE = 25,
SWIFTIDE_COMPLETION_KIND_AFTERPOUNDEXPR = 26,
SWIFTIDE_COMPLETION_KIND_AFTERPOUNDDIRECTIVE = 27,
SWIFTIDE_COMPLETION_KIND_PLATFORMCONDITON = 28,
SWIFTIDE_COMPLETION_KIND_AFTERIFSTMTELSE = 29,
SWIFTIDE_COMPLETION_KIND_GENERICREQUIREMENT = 30,
SWIFTIDE_COMPLETION_KIND_PRECEDENCEGROUP = 31,
SWIFTIDE_COMPLETION_KIND_STMTLABEL = 32,
SWIFTIDE_COMPLETION_KIND_EFFECTSSPECIFIER = 33,
SWIFTIDE_COMPLETION_KIND_FOREACHPATTERNBEGINNING = 34,
SWIFTIDE_COMPLETION_KIND_TYPEATTRBEGINNING = 35,
SWIFTIDE_COMPLETION_KIND_OPTIONALBINDING = 36,
SWIFTIDE_COMPLETION_KIND_FOREACHKWIN = 37,
/*obsoleted*/ SWIFTIDE_COMPLETION_KIND_WITHOUTCONSTRAINTTYPE = 38,
SWIFTIDE_COMPLETION_KIND_THENSTMTEXPR = 39,
SWIFTIDE_COMPLETION_KIND_TYPEBEGINNING = 40,
SWIFTIDE_COMPLETION_KIND_TYPESIMPLEORCOMPOSITION = 41,
SWIFTIDE_COMPLETION_KIND_TYPEPOSSIBLEFUNCTIONPARAMBEGINNING = 42,
SWIFTIDE_COMPLETION_KIND_TYPEATTRINHERITANCEBEGINNING = 43,
SWIFTIDE_COMPLETION_KIND_TYPESIMPLEINVERTED = 44,
} swiftide_completion_kind_t;
typedef enum {
SWIFTIDE_COMPLETION_ITEM_KIND_DECLARATION = 0,
SWIFTIDE_COMPLETION_ITEM_KIND_KEYWORD = 1,
SWIFTIDE_COMPLETION_ITEM_KIND_PATTERN = 2,
SWIFTIDE_COMPLETION_ITEM_KIND_LITERAL = 3,
SWIFTIDE_COMPLETION_ITEM_KIND_BUILTINOPERATOR = 4,
} swiftide_completion_item_kind_t;
typedef enum {
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_MODULE = 0,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_CLASS = 1,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_STRUCT = 2,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_ENUM = 3,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_ENUMELEMENT = 4,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_PROTOCOL = 5,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_ASSOCIATEDTYPE = 6,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_TYPEALIAS = 7,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_GENERICTYPEPARAM = 8,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_CONSTRUCTOR = 9,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_DESTRUCTOR = 10,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_SUBSCRIPT = 11,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_STATICMETHOD = 12,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_INSTANCEMETHOD = 13,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_PREFIXOPERATORFUNCTION = 14,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_POSTFIXOPERATORFUNCTION = 15,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_INFIXOPERATORFUNCTION = 16,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_FREEFUNCTION = 17,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_STATICVAR = 18,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_INSTANCEVAR = 19,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_LOCALVAR = 20,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_GLOBALVAR = 21,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_PRECEDENCEGROUP = 22,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_ACTOR = 23,
SWIFTIDE_COMPLETION_ITEM_DECL_KIND_MACRO = 24,
} swiftide_completion_item_decl_kind_t;
typedef enum {
SWIFTIDE_COMPLETION_TYPE_RELATION_NOTAPPLICABLE = 0,
SWIFTIDE_COMPLETION_TYPE_RELATION_UNKNOWN = 1,
SWIFTIDE_COMPLETION_TYPE_RELATION_UNRELATED = 2,
SWIFTIDE_COMPLETION_TYPE_RELATION_INVALID = 3,
SWIFTIDE_COMPLETION_TYPE_RELATION_CONVERTIBLE = 4,
SWIFTIDE_COMPLETION_TYPE_RELATION_IDENTICAL = 5,
} swiftide_completion_type_relation_t;
typedef enum {
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_NONE = 0,
/* obsoleted */ SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_EXPRESSIONSPECIFIC = 1,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_LOCAL = 2,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_CURRENTNOMINAL = 3,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_SUPER = 4,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_OUTSIDENOMINAL = 5,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_CURRENTMODULE = 6,
SWIFTIDE_COMPLETION_SEMANTIC_CONTEXT_OTHERMODULE = 7,
} swiftide_completion_semantic_context_t;
typedef enum {
SWIFTIDE_COMPLETION_FLAIR_EXPRESSIONSPECIFIC = 1 << 0,
SWIFTIDE_COMPLETION_FLAIR_SUPERCHAIN = 1 << 1,
SWIFTIDE_COMPLETION_FLAIR_ARGUMENTLABELS = 1 << 2,
SWIFTIDE_COMPLETION_FLAIR_COMMONKEYWORDATCURRENTPOSITION = 1 << 3,
SWIFTIDE_COMPLETION_FLAIR_RAREKEYWORDATCURRENTPOSITION = 1 << 4,
SWIFTIDE_COMPLETION_FLAIR_RARETYPEATCURRENTPOSITION = 1 << 5,
SWIFTIDE_COMPLETION_FLAIR_EXPRESSIONATNONSCRIPTORMAINFILESCOPE = 1 << 6,
} swiftide_completion_flair_t;
typedef enum {
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_NONE = 0,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_REDUNDANT_IMPORT = 1,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_DEPRECATED = 2,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_INVALID_ASYNC_CONTEXT = 3,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_CROSS_ACTOR_REFERENCE = 4,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_VARIABLE_USED_IN_OWN_DEFINITION = 5,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_REDUNDANT_IMPORT_INDIRECT = 6,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_SOFTDEPRECATED = 7,
SWIFTIDE_COMPLETION_NOT_RECOMMENDED_NON_ASYNC_ALTERNATIVE_USED_IN_ASYNC_CONTEXT =
8,
} swiftide_completion_not_recommended_reason_t;
typedef enum {
SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_NONE = 0,
SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_ERROR = 1,
SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_WARNING = 2,
SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_REMARK = 3,
SWIFTIDE_COMPLETION_DIAGNOSTIC_SEVERITY_NOTE = 4,
} swiftide_completion_diagnostic_severity_t;
typedef void *swiftide_completion_request_t;
typedef void *swiftide_completion_response_t;
typedef void *swiftide_fuzzy_match_pattern_t;
typedef void *swiftide_cache_invalidation_options_t;
/// swiftide equivalent of sourcekitd_request_handle_t
typedef const void *swiftide_request_handle_t;
//=== Functions -----------------------------------------------------------===//
SWIFTIDE_DEPRECATED(
"Use swiftide_connection_create_with_inspection_instance instead")
SWIFTIDE_PUBLIC swiftide_connection_t swiftide_connection_create(void);
SWIFTIDE_PUBLIC swiftide_connection_t
swiftide_connection_create_with_inspection_instance(
void *opqueSwiftIDEInspectionInstance);
SWIFTIDE_PUBLIC void swiftide_connection_dispose(swiftide_connection_t);
SWIFTIDE_PUBLIC void
swiftide_connection_mark_cached_compiler_instance_should_be_invalidated(
swiftide_connection_t, swiftide_cache_invalidation_options_t);
/// Override the contents of the file \p path with \p contents. If \p contents
/// is NULL, go back to using the real the file system.
SWIFTIDE_PUBLIC void
swiftide_set_file_contents(swiftide_connection_t connection, const char *path,
const char *contents);
/// Cancel the request with \p handle.
SWIFTIDE_PUBLIC void swiftide_cancel_request(swiftide_connection_t _conn,
swiftide_request_handle_t handle);
SWIFTIDE_PUBLIC swiftide_completion_request_t
swiftide_completion_request_create(const char *path, uint32_t offset,
char *const *const compiler_args,
uint32_t num_compiler_args);
SWIFTIDE_PUBLIC void
swiftide_completion_request_dispose(swiftide_completion_request_t);
SWIFTIDE_PUBLIC void
swiftide_completion_request_set_annotate_result(swiftide_completion_request_t,
bool);
SWIFTIDE_PUBLIC void swiftide_completion_request_set_include_objectliterals(
swiftide_completion_request_t, bool);
SWIFTIDE_PUBLIC void swiftide_completion_request_set_add_inits_to_top_level(
swiftide_completion_request_t, bool);
SWIFTIDE_PUBLIC void
swiftide_completion_request_set_add_call_with_no_default_args(
swiftide_completion_request_t, bool);
/// Same as swiftide_complete but supports cancellation.
/// This request is identified by \p handle. Calling swiftide_cancel_request
/// with that handle cancels the request.
/// Note that the caller is responsible for creating a unique request handle.
/// This differs from the sourcekitd functions in which SourceKit creates a
/// unique handle and passes it to the client via an out parameter.
SWIFTIDE_PUBLIC swiftide_completion_response_t swiftide_complete_cancellable(
swiftide_connection_t _conn, swiftide_completion_request_t _req,
swiftide_request_handle_t handle);
SWIFTIDE_DEPRECATED("Use swiftide_complete_cancellable instead")
SWIFTIDE_PUBLIC swiftide_completion_response_t swiftide_complete(
swiftide_connection_t provider, swiftide_completion_request_t);
SWIFTIDE_PUBLIC void
swiftide_completion_result_dispose(swiftide_completion_response_t);
SWIFTIDE_PUBLIC bool
swiftide_completion_result_is_error(swiftide_completion_response_t);
/// Result has the same lifetime as the result.
SWIFTIDE_PUBLIC const char *swiftide_completion_result_get_error_description(
swiftide_completion_response_t);
SWIFTIDE_PUBLIC bool
swiftide_completion_result_is_cancelled(swiftide_completion_response_t);
/// Copies a string representation of the completion result. This string should
/// be disposed of with \c free when done.
SWIFTIDE_PUBLIC const char *
swiftide_completion_result_description_copy(swiftide_completion_response_t);
SWIFTIDE_PUBLIC void swiftide_completion_result_get_completions(
swiftide_completion_response_t,
void (^completions_handler)(const swiftide_completion_item_t *completions,
const char **filter_names,
uint64_t num_completions));
SWIFTIDE_PUBLIC swiftide_completion_item_t
swiftide_completion_result_get_completion_at_index(
swiftide_completion_response_t, uint64_t index);
SWIFTIDE_PUBLIC swiftide_completion_kind_t
swiftide_completion_result_get_kind(swiftide_completion_response_t);
SWIFTIDE_PUBLIC void swiftide_completion_result_foreach_baseexpr_typename(
swiftide_completion_response_t, bool (^handler)(const char *));
SWIFTIDE_PUBLIC bool swiftide_completion_result_is_reusing_astcontext(
swiftide_completion_response_t);
/// Copies a string representation of the completion item. This string should
/// be disposed of with \c free when done.
SWIFTIDE_PUBLIC const char *
swiftide_completion_item_description_copy(swiftide_completion_item_t);
SWIFTIDE_PUBLIC void
swiftide_completion_item_get_label(swiftide_completion_response_t,
swiftide_completion_item_t, bool annotate,
void (^handler)(const char *));
SWIFTIDE_PUBLIC void
swiftide_completion_item_get_source_text(swiftide_completion_response_t,
swiftide_completion_item_t,
void (^handler)(const char *));
SWIFTIDE_PUBLIC void swiftide_completion_item_get_type_name(
swiftide_completion_response_t, swiftide_completion_item_t, bool annotate,
void (^handler)(const char *));
SWIFTIDE_PUBLIC void
swiftide_completion_item_get_doc_brief(swiftide_completion_response_t,
swiftide_completion_item_t,
void (^handler)(const char *));
SWIFTIDE_PUBLIC void swiftide_completion_item_get_associated_usrs(
swiftide_completion_response_t, swiftide_completion_item_t,
void (^handler)(const char **, uint64_t));
SWIFTIDE_PUBLIC
uint32_t swiftide_completion_item_get_kind(swiftide_completion_item_t);
SWIFTIDE_PUBLIC uint32_t
swiftide_completion_item_get_associated_kind(swiftide_completion_item_t);
SWIFTIDE_PUBLIC uint32_t
swiftide_completion_item_get_semantic_context(swiftide_completion_item_t);
SWIFTIDE_PUBLIC
uint32_t swiftide_completion_item_get_flair(swiftide_completion_item_t);
SWIFTIDE_PUBLIC bool
swiftide_completion_item_is_not_recommended(swiftide_completion_item_t);
SWIFTIDE_PUBLIC uint32_t
swiftide_completion_item_not_recommended_reason(swiftide_completion_item_t);
SWIFTIDE_PUBLIC bool
swiftide_completion_item_has_diagnostic(swiftide_completion_item_t _item);
SWIFTIDE_PUBLIC void swiftide_completion_item_get_diagnostic(
swiftide_completion_response_t, swiftide_completion_item_t,
void (^handler)(swiftide_completion_diagnostic_severity_t, const char *));
SWIFTIDE_PUBLIC bool
swiftide_completion_item_is_system(swiftide_completion_item_t);
/// Call \p handler with the name of the module the code completion item
/// \p _item is defined in. The module may be \c nullptr for e.g. keywords.
SWIFTIDE_PUBLIC
void swiftide_completion_item_get_module_name(
swiftide_completion_response_t _response, swiftide_completion_item_t _item,
void (^handler)(const char *));
SWIFTIDE_PUBLIC uint32_t
swiftide_completion_item_get_num_bytes_to_erase(swiftide_completion_item_t);
SWIFTIDE_PUBLIC uint32_t
swiftide_completion_item_get_type_relation(swiftide_completion_item_t);
/// Returns 0 for items not in an external module, and ~0u if the other module
/// is not imported or the depth is otherwise unknown.
SWIFTIDE_PUBLIC uint32_t swiftide_completion_item_import_depth(
swiftide_completion_response_t, swiftide_completion_item_t);
SWIFTIDE_PUBLIC swiftide_fuzzy_match_pattern_t
swiftide_fuzzy_match_pattern_create(const char *pattern);
SWIFTIDE_PUBLIC bool swiftide_fuzzy_match_pattern_matches_candidate(
swiftide_fuzzy_match_pattern_t pattern, const char *candidate,
double *outScore);
SWIFTIDE_PUBLIC void
swiftide_fuzzy_match_pattern_dispose(swiftide_fuzzy_match_pattern_t);
SWIFTIDE_END_DECLS
#endif

View File

@@ -1,5 +1,7 @@
framework module sourcekitdInProc {
umbrella header "sourcekitd.h"
header "plugin.h"
header "CodeCompletionSwiftInterop.h"
export *
module * { export * }
}

View File

@@ -2,33 +2,68 @@ sourcekitd_cancel_request
sourcekitd_request_handle_dispose
sourcekitd_initialize
sourcekitd_request_array_create
sourcekitd_request_array_get_bool
sourcekitd_request_array_get_count
sourcekitd_request_array_get_int64
sourcekitd_request_array_get_string
sourcekitd_request_array_get_uid
sourcekitd_request_array_get_value
sourcekitd_request_array_set_int64
sourcekitd_request_array_set_string
sourcekitd_request_array_set_stringbuf
sourcekitd_request_array_set_uid
sourcekitd_request_array_set_value
sourcekitd_request_bool_get_value
sourcekitd_request_create_from_yaml
sourcekitd_request_description_copy
sourcekitd_request_description_dump
sourcekitd_request_dictionary_create
sourcekitd_request_dictionary_get_bool
sourcekitd_request_dictionary_get_int64
sourcekitd_request_dictionary_get_string
sourcekitd_request_dictionary_get_uid
sourcekitd_request_dictionary_get_value
sourcekitd_request_dictionary_set_int64
sourcekitd_request_dictionary_set_string
sourcekitd_request_dictionary_set_stringbuf
sourcekitd_request_dictionary_set_uid
sourcekitd_request_dictionary_set_value
sourcekitd_request_get_type
sourcekitd_request_int64_create
sourcekitd_request_retain
sourcekitd_request_int64_get_value
sourcekitd_request_release
sourcekitd_request_retain
sourcekitd_request_string_create
sourcekitd_request_string_get_length
sourcekitd_request_string_get_ptr
sourcekitd_request_uid_create
sourcekitd_request_uid_get_value
sourcekitd_response_array_create
sourcekitd_response_array_set_int64
sourcekitd_response_array_set_double
sourcekitd_response_array_set_string
sourcekitd_response_array_set_stringbuf
sourcekitd_response_array_set_uid
sourcekitd_response_array_set_value
sourcekitd_response_description_copy
sourcekitd_response_description_dump
sourcekitd_response_description_dump_filedesc
sourcekitd_response_dictionary_create
sourcekitd_response_dictionary_set_bool
sourcekitd_response_dictionary_set_double
sourcekitd_response_dictionary_set_custom_buffer
sourcekitd_response_dictionary_set_int64
sourcekitd_response_dictionary_set_string
sourcekitd_response_dictionary_set_stringbuf
sourcekitd_response_dictionary_set_uid
sourcekitd_response_dictionary_set_value
sourcekitd_response_dispose
sourcekitd_response_error_create
sourcekitd_response_error_get_description
sourcekitd_response_error_get_kind
sourcekitd_response_get_value
sourcekitd_response_is_error
sourcekitd_response_retain
sourcekitd_send_request
sourcekitd_send_request_sync
sourcekitd_set_interrupted_connection_handler
@@ -43,30 +78,115 @@ sourcekitd_uid_get_string_ptr
sourcekitd_variant_array_apply
sourcekitd_variant_array_apply_f
sourcekitd_variant_array_get_bool
sourcekitd_variant_array_get_double
sourcekitd_variant_array_get_count
sourcekitd_variant_array_get_int64
sourcekitd_variant_array_get_string
sourcekitd_variant_array_get_uid
sourcekitd_variant_array_get_value
sourcekitd_variant_bool_get_value
sourcekitd_variant_double_get_value
sourcekitd_variant_description_copy
sourcekitd_variant_description_dump
sourcekitd_variant_description_dump_filedesc
sourcekitd_variant_dictionary_apply
sourcekitd_variant_dictionary_apply_f
sourcekitd_variant_dictionary_get_bool
sourcekitd_variant_dictionary_get_double
sourcekitd_variant_dictionary_get_int64
sourcekitd_variant_dictionary_get_string
sourcekitd_variant_dictionary_get_value
sourcekitd_variant_dictionary_get_uid
sourcekitd_variant_dictionary_get_value
sourcekitd_variant_get_type
sourcekitd_variant_json_description_copy
sourcekitd_variant_string_get_length
sourcekitd_variant_string_get_ptr
sourcekitd_variant_data_get_size
sourcekitd_variant_data_get_ptr
sourcekitd_variant_data_get_size
sourcekitd_variant_int64_get_value
sourcekitd_variant_uid_get_value
sourcekitd_variant_functions_create
sourcekitd_variant_functions_set_get_type
sourcekitd_variant_functions_set_array_apply
sourcekitd_variant_functions_set_array_get_bool
sourcekitd_variant_functions_set_array_get_double
sourcekitd_variant_functions_set_array_get_count
sourcekitd_variant_functions_set_array_get_int64
sourcekitd_variant_functions_set_array_get_string
sourcekitd_variant_functions_set_array_get_uid
sourcekitd_variant_functions_set_array_get_value
sourcekitd_variant_functions_set_bool_get_value
sourcekitd_variant_functions_set_double_get_value
sourcekitd_variant_functions_set_dictionary_apply
sourcekitd_variant_functions_set_dictionary_get_bool
sourcekitd_variant_functions_set_dictionary_get_double
sourcekitd_variant_functions_set_dictionary_get_int64
sourcekitd_variant_functions_set_dictionary_get_string
sourcekitd_variant_functions_set_dictionary_get_value
sourcekitd_variant_functions_set_dictionary_get_uid
sourcekitd_variant_functions_set_string_get_length
sourcekitd_variant_functions_set_string_get_ptr
sourcekitd_variant_functions_set_int64_get_value
sourcekitd_variant_functions_set_uid_get_value
sourcekitd_variant_functions_set_data_get_size
sourcekitd_variant_functions_set_data_get_ptr
sourcekitd_plugin_initialize_is_client_only
sourcekitd_plugin_initialize_custom_buffer_start
sourcekitd_plugin_initialize_uid_get_from_cstr
sourcekitd_plugin_initialize_uid_get_string_ptr
sourcekitd_plugin_initialize_register_request_handler
sourcekitd_plugin_initialize_register_cancellable_request_handler
sourcekitd_plugin_initialize_register_cancellation_handler
sourcekitd_plugin_initialize_register_custom_buffer
sourcekitd_plugin_initialize_get_swift_ide_inspection_instance
sourcekitd_register_plugin_path
sourcekitd_load_client_plugins
swiftide_cancel_request
swiftide_complete
swiftide_complete_cancellable
swiftide_completion_item_description_copy
swiftide_completion_item_get_associated_kind
swiftide_completion_item_get_associated_usrs
swiftide_completion_item_get_diagnostic
swiftide_completion_item_get_doc_brief
swiftide_completion_item_get_flair
swiftide_completion_item_get_kind
swiftide_completion_item_get_label
swiftide_completion_item_get_module_name
swiftide_completion_item_get_num_bytes_to_erase
swiftide_completion_item_get_semantic_context
swiftide_completion_item_get_source_text
swiftide_completion_item_get_type_name
swiftide_completion_item_get_type_relation
swiftide_completion_item_has_diagnostic
swiftide_completion_item_import_depth
swiftide_completion_item_is_not_recommended
swiftide_completion_item_is_system
swiftide_completion_item_not_recommended_reason
swiftide_completion_request_create
swiftide_completion_request_dispose
swiftide_completion_request_set_add_call_with_no_default_args
swiftide_completion_request_set_add_inits_to_top_level
swiftide_completion_request_set_annotate_result
swiftide_completion_request_set_include_objectliterals
swiftide_completion_result_description_copy
swiftide_completion_result_dispose
swiftide_completion_result_foreach_baseexpr_typename
swiftide_completion_result_get_completion_at_index
swiftide_completion_result_get_completions
swiftide_completion_result_get_error_description
swiftide_completion_result_get_kind
swiftide_completion_result_is_cancelled
swiftide_completion_result_is_error
swiftide_completion_result_is_reusing_astcontext
swiftide_connection_create
swiftide_connection_create_with_inspection_instance
swiftide_connection_dispose
swiftide_connection_mark_cached_compiler_instance_should_be_invalidated
swiftide_fuzzy_match_pattern_create
swiftide_fuzzy_match_pattern_dispose
swiftide_fuzzy_match_pattern_matches_candidate
swiftide_set_file_contents
_ZN10sourcekitd13cancelRequestEPKv
_ZN10sourcekitd13enableLoggingEN4llvm9StringRefE
_ZN10sourcekitd13handleRequestEPvPKvNSt3__18functionIFvS0_EEE
@@ -76,6 +196,11 @@ _ZN10sourcekitd27sendBarriersEnabledResponseENSt3__18functionIFvPvEEE
_ZN10sourcekitd17initializeServiceEN4llvm9StringRefES1_S1_NSt3__18functionIFvPvEEE
_ZN10sourcekitd24createErrorRequestFailedEN4llvm9StringRefE
_ZN10sourcekitd24disposeCancellationTokenEPKv
_ZN10sourcekitd11loadPluginsEN4llvm8ArrayRefINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEERNS_16PluginInitParamsE
_ZN10sourcekitd41pluginGetOpaqueSwiftIDEInspectionInstanceEv
_ZN10sourcekitd28pluginRegisterRequestHandlerEU13block_pointerFbPvPKvU13block_pointerFvS0_EE
_ZN10sourcekitd33pluginRegisterCancellationHandlerEU13block_pointerFvPKvE
_ZN10sourcekitd16PluginInitParamsC1EbNSt3__18functionIFvU13block_pointerFbPvPKvU13block_pointerFvS3_EEEEENS2_IFvU13block_pointerFvS5_EEEES3_
_ZN9SourceKit6Logger12LoggingLevelE
_ZN9SourceKit6LoggerD1Ev
_ZN9SourceKit6UIdent6setTagEPv

View File

@@ -12,6 +12,7 @@
#include "sourcekitd/Internal.h"
#include "sourcekitd/Service.h"
#include "sourcekitd/sourcekitdInProc-Internal.h"
#include "SourceKit/Support/Concurrency.h"
#include "SourceKit/Support/Logging.h"
@@ -83,36 +84,51 @@ static void getToolchainPrefixPath(llvm::SmallVectorImpl<char> &Path) {
llvm::sys::path::remove_filename(Path);
}
static std::string getRuntimeLibPath() {
std::string sourcekitdInProc::getRuntimeLibPath() {
llvm::SmallString<128> libPath;
getToolchainPrefixPath(libPath);
llvm::sys::path::append(libPath, "lib");
return libPath.str().str();
}
static std::string getSwiftExecutablePath() {
std::string sourcekitdInProc::getSwiftExecutablePath() {
llvm::SmallString<128> path;
getToolchainPrefixPath(path);
llvm::sys::path::append(path, "bin", "swift-frontend");
return path.str().str();
}
static std::string getDiagnosticDocumentationPath() {
std::string sourcekitdInProc::getDiagnosticDocumentationPath() {
llvm::SmallString<128> docPath;
getToolchainPrefixPath(docPath);
llvm::sys::path::append(docPath, "share", "doc", "swift", "diagnostics");
return docPath.str().str();
}
static std::vector<std::string> registeredPlugins;
void sourcekitd_load_client_plugins(void) {
// There should be no independent client.
}
void sourcekitd_initialize(void) {
assert(msgHandlingQueue == nullptr && "Cannot initialize service twice");
msgHandlingQueue = new WorkQueue(WorkQueue::Dequeuing::Concurrent,
"sourcekitdInProc.msgHandlingQueue");
if (sourcekitd::initializeClient()) {
LOG_INFO_FUNC(High, "initializing");
sourcekitd::initializeService(getSwiftExecutablePath(), getRuntimeLibPath(),
getDiagnosticDocumentationPath(),
postNotification);
sourcekitd::initializeService(
sourcekitdInProc::getSwiftExecutablePath(),
sourcekitdInProc::getRuntimeLibPath(),
sourcekitdInProc::getDiagnosticDocumentationPath(), postNotification);
static std::once_flag flag;
std::call_once(flag, [] {
sourcekitd::PluginInitParams pluginParams(
/*isClientOnly=*/false, sourcekitd::pluginRegisterRequestHandler,
sourcekitd::pluginRegisterCancellationHandler,
sourcekitd::pluginGetOpaqueSwiftIDEInspectionInstance());
sourcekitd::loadPlugins(registeredPlugins, pluginParams);
});
}
}
@@ -123,6 +139,13 @@ void sourcekitd_shutdown(void) {
}
}
void sourcekitd_register_plugin_path(const char *clientPlugin,
const char *servicePlugin) {
(void)clientPlugin; // sourcekitdInProc has no independent client.
if (servicePlugin)
registeredPlugins.push_back(servicePlugin);
}
void sourcekitd::set_interrupted_connection_handler(
llvm::function_ref<void()> handler) {
}

View File

@@ -2,33 +2,68 @@ sourcekitd_cancel_request
sourcekitd_request_handle_dispose
sourcekitd_initialize
sourcekitd_request_array_create
sourcekitd_request_array_get_bool
sourcekitd_request_array_get_count
sourcekitd_request_array_get_int64
sourcekitd_request_array_get_string
sourcekitd_request_array_get_uid
sourcekitd_request_array_get_value
sourcekitd_request_array_set_int64
sourcekitd_request_array_set_string
sourcekitd_request_array_set_stringbuf
sourcekitd_request_array_set_uid
sourcekitd_request_array_set_value
sourcekitd_request_bool_get_value
sourcekitd_request_create_from_yaml
sourcekitd_request_description_copy
sourcekitd_request_description_dump
sourcekitd_request_dictionary_create
sourcekitd_request_dictionary_get_bool
sourcekitd_request_dictionary_get_int64
sourcekitd_request_dictionary_get_string
sourcekitd_request_dictionary_get_uid
sourcekitd_request_dictionary_get_value
sourcekitd_request_dictionary_set_int64
sourcekitd_request_dictionary_set_string
sourcekitd_request_dictionary_set_stringbuf
sourcekitd_request_dictionary_set_uid
sourcekitd_request_dictionary_set_value
sourcekitd_request_get_type
sourcekitd_request_int64_create
sourcekitd_request_retain
sourcekitd_request_int64_get_value
sourcekitd_request_release
sourcekitd_request_retain
sourcekitd_request_string_create
sourcekitd_request_string_get_length
sourcekitd_request_string_get_ptr
sourcekitd_request_uid_create
sourcekitd_request_uid_get_value
sourcekitd_response_array_create
sourcekitd_response_array_set_int64
sourcekitd_response_array_set_double
sourcekitd_response_array_set_string
sourcekitd_response_array_set_stringbuf
sourcekitd_response_array_set_uid
sourcekitd_response_array_set_value
sourcekitd_response_description_copy
sourcekitd_response_description_dump
sourcekitd_response_description_dump_filedesc
sourcekitd_response_dictionary_create
sourcekitd_response_dictionary_set_bool
sourcekitd_response_dictionary_set_double
sourcekitd_response_dictionary_set_custom_buffer
sourcekitd_response_dictionary_set_int64
sourcekitd_response_dictionary_set_string
sourcekitd_response_dictionary_set_stringbuf
sourcekitd_response_dictionary_set_uid
sourcekitd_response_dictionary_set_value
sourcekitd_response_dispose
sourcekitd_response_error_create
sourcekitd_response_error_get_description
sourcekitd_response_error_get_kind
sourcekitd_response_get_value
sourcekitd_response_is_error
sourcekitd_response_retain
sourcekitd_send_request
sourcekitd_send_request_sync
sourcekitd_set_interrupted_connection_handler
@@ -43,27 +78,112 @@ sourcekitd_uid_get_string_ptr
sourcekitd_variant_array_apply
sourcekitd_variant_array_apply_f
sourcekitd_variant_array_get_bool
sourcekitd_variant_array_get_double
sourcekitd_variant_array_get_count
sourcekitd_variant_array_get_int64
sourcekitd_variant_array_get_string
sourcekitd_variant_array_get_uid
sourcekitd_variant_array_get_value
sourcekitd_variant_bool_get_value
sourcekitd_variant_double_get_value
sourcekitd_variant_description_copy
sourcekitd_variant_description_dump
sourcekitd_variant_description_dump_filedesc
sourcekitd_variant_dictionary_apply
sourcekitd_variant_dictionary_apply_f
sourcekitd_variant_dictionary_get_bool
sourcekitd_variant_dictionary_get_double
sourcekitd_variant_dictionary_get_int64
sourcekitd_variant_dictionary_get_string
sourcekitd_variant_dictionary_get_value
sourcekitd_variant_dictionary_get_uid
sourcekitd_variant_dictionary_get_value
sourcekitd_variant_get_type
sourcekitd_variant_json_description_copy
sourcekitd_variant_string_get_length
sourcekitd_variant_string_get_ptr
sourcekitd_variant_data_get_size
sourcekitd_variant_data_get_ptr
sourcekitd_variant_data_get_size
sourcekitd_variant_int64_get_value
sourcekitd_variant_uid_get_value
sourcekitd_variant_functions_create
sourcekitd_variant_functions_set_get_type
sourcekitd_variant_functions_set_array_apply
sourcekitd_variant_functions_set_array_get_bool
sourcekitd_variant_functions_set_array_get_double
sourcekitd_variant_functions_set_array_get_count
sourcekitd_variant_functions_set_array_get_int64
sourcekitd_variant_functions_set_array_get_string
sourcekitd_variant_functions_set_array_get_uid
sourcekitd_variant_functions_set_array_get_value
sourcekitd_variant_functions_set_bool_get_value
sourcekitd_variant_functions_set_double_get_value
sourcekitd_variant_functions_set_dictionary_apply
sourcekitd_variant_functions_set_dictionary_get_bool
sourcekitd_variant_functions_set_dictionary_get_double
sourcekitd_variant_functions_set_dictionary_get_int64
sourcekitd_variant_functions_set_dictionary_get_string
sourcekitd_variant_functions_set_dictionary_get_value
sourcekitd_variant_functions_set_dictionary_get_uid
sourcekitd_variant_functions_set_string_get_length
sourcekitd_variant_functions_set_string_get_ptr
sourcekitd_variant_functions_set_int64_get_value
sourcekitd_variant_functions_set_uid_get_value
sourcekitd_variant_functions_set_data_get_size
sourcekitd_variant_functions_set_data_get_ptr
sourcekitd_plugin_initialize_is_client_only
sourcekitd_plugin_initialize_custom_buffer_start
sourcekitd_plugin_initialize_uid_get_from_cstr
sourcekitd_plugin_initialize_uid_get_string_ptr
sourcekitd_plugin_initialize_register_request_handler
sourcekitd_plugin_initialize_register_cancellable_request_handler
sourcekitd_plugin_initialize_register_cancellation_handler
sourcekitd_plugin_initialize_register_custom_buffer
sourcekitd_plugin_initialize_get_swift_ide_inspection_instance
sourcekitd_register_plugin_path
sourcekitd_load_client_plugins
swiftide_cancel_request
swiftide_complete
swiftide_complete_cancellable
swiftide_completion_item_description_copy
swiftide_completion_item_get_associated_kind
swiftide_completion_item_get_associated_usrs
swiftide_completion_item_get_diagnostic
swiftide_completion_item_get_doc_brief
swiftide_completion_item_get_flair
swiftide_completion_item_get_kind
swiftide_completion_item_get_label
swiftide_completion_item_get_module_name
swiftide_completion_item_get_num_bytes_to_erase
swiftide_completion_item_get_semantic_context
swiftide_completion_item_get_source_text
swiftide_completion_item_get_type_name
swiftide_completion_item_get_type_relation
swiftide_completion_item_has_diagnostic
swiftide_completion_item_import_depth
swiftide_completion_item_is_not_recommended
swiftide_completion_item_is_system
swiftide_completion_item_not_recommended_reason
swiftide_completion_request_create
swiftide_completion_request_dispose
swiftide_completion_request_set_add_call_with_no_default_args
swiftide_completion_request_set_add_inits_to_top_level
swiftide_completion_request_set_annotate_result
swiftide_completion_request_set_include_objectliterals
swiftide_completion_result_description_copy
swiftide_completion_result_dispose
swiftide_completion_result_foreach_baseexpr_typename
swiftide_completion_result_get_completion_at_index
swiftide_completion_result_get_completions
swiftide_completion_result_get_error_description
swiftide_completion_result_get_kind
swiftide_completion_result_is_cancelled
swiftide_completion_result_is_error
swiftide_completion_result_is_reusing_astcontext
swiftide_connection_create
swiftide_connection_create_with_inspection_instance
swiftide_connection_dispose
swiftide_connection_mark_cached_compiler_instance_should_be_invalidated
swiftide_fuzzy_match_pattern_create
swiftide_fuzzy_match_pattern_dispose
swiftide_fuzzy_match_pattern_matches_candidate
swiftide_set_file_contents

View File

@@ -238,6 +238,9 @@ void sourcekitd_request_handle_dispose(sourcekitd_request_handle_t handle) {
xpc_release(msg);
}
static std::vector<std::string> registeredClientPlugins;
static std::vector<std::string> registeredServicePlugins;
/// To avoid repeated crashes, used to notify the service to delay typechecking
/// in the editor for a certain amount of seconds.
static std::atomic<size_t> SemanticEditorDelaySecondsNum;
@@ -246,6 +249,14 @@ static void handleInternalInitRequest(xpc_object_t reply) {
size_t Delay = SemanticEditorDelaySecondsNum;
if (Delay != 0)
xpc_dictionary_set_uint64(reply, xpc::KeySemaEditorDelay, Delay);
if (!registeredServicePlugins.empty()) {
auto plugins = xpc_array_create(nullptr, 0);
for (const auto &plugin : registeredServicePlugins)
xpc_array_set_string(plugins, XPC_ARRAY_APPEND, plugin.c_str());
xpc_dictionary_set_value(reply, xpc::KeyPlugins, plugins);
xpc_release(plugins);
}
}
static void handleInternalUIDRequest(xpc_object_t XVal,
@@ -343,10 +354,21 @@ static void initializeXPCClient() {
xpc_connection_resume(GlobalConn);
}
void sourcekitd_load_client_plugins(void) {
static std::once_flag flag;
std::call_once(flag, [] {
sourcekitd::PluginInitParams pluginParams(
/*isClientOnly=*/true, /*registerRequestHandler=*/nullptr,
/*registerCancellationHandler=*/nullptr);
loadPlugins(registeredClientPlugins, pluginParams);
});
}
void sourcekitd_initialize(void) {
if (sourcekitd::initializeClient()) {
LOG_INFO_FUNC(High, "initializing");
initializeXPCClient();
sourcekitd_load_client_plugins();
}
}
@@ -358,6 +380,15 @@ void sourcekitd_shutdown(void) {
}
}
void sourcekitd_register_plugin_path(const char *clientPlugin,
const char *servicePlugin) {
assert(!GlobalConn && "plugin registered after sourcekitd_initialize");
if (clientPlugin)
registeredClientPlugins.push_back(clientPlugin);
if (servicePlugin)
registeredServicePlugins.push_back(servicePlugin);
}
static xpc_connection_t getGlobalConnection() {
assert(GlobalConn);
return GlobalConn;

View File

@@ -43,18 +43,21 @@ sourcekitd_uid_get_string_ptr
sourcekitd_variant_array_apply
sourcekitd_variant_array_apply_f
sourcekitd_variant_array_get_bool
sourcekitd_variant_array_get_double
sourcekitd_variant_array_get_count
sourcekitd_variant_array_get_int64
sourcekitd_variant_array_get_string
sourcekitd_variant_array_get_uid
sourcekitd_variant_array_get_value
sourcekitd_variant_bool_get_value
sourcekitd_variant_double_get_value
sourcekitd_variant_description_copy
sourcekitd_variant_description_dump
sourcekitd_variant_description_dump_filedesc
sourcekitd_variant_dictionary_apply
sourcekitd_variant_dictionary_apply_f
sourcekitd_variant_dictionary_get_bool
sourcekitd_variant_dictionary_get_double
sourcekitd_variant_dictionary_get_int64
sourcekitd_variant_dictionary_get_string
sourcekitd_variant_dictionary_get_value
@@ -67,3 +70,36 @@ sourcekitd_variant_data_get_size
sourcekitd_variant_data_get_ptr
sourcekitd_variant_int64_get_value
sourcekitd_variant_uid_get_value
sourcekitd_variant_functions_create
sourcekitd_variant_functions_set_get_type
sourcekitd_variant_functions_set_array_apply
sourcekitd_variant_functions_set_array_get_bool
sourcekitd_variant_functions_set_array_get_double
sourcekitd_variant_functions_set_array_get_count
sourcekitd_variant_functions_set_array_get_int64
sourcekitd_variant_functions_set_array_get_string
sourcekitd_variant_functions_set_array_get_uid
sourcekitd_variant_functions_set_array_get_value
sourcekitd_variant_functions_set_bool_get_value
sourcekitd_variant_functions_set_double_get_value
sourcekitd_variant_functions_set_dictionary_apply
sourcekitd_variant_functions_set_dictionary_get_bool
sourcekitd_variant_functions_set_dictionary_get_double
sourcekitd_variant_functions_set_dictionary_get_int64
sourcekitd_variant_functions_set_dictionary_get_string
sourcekitd_variant_functions_set_dictionary_get_value
sourcekitd_variant_functions_set_dictionary_get_uid
sourcekitd_variant_functions_set_string_get_length
sourcekitd_variant_functions_set_string_get_ptr
sourcekitd_variant_functions_set_int64_get_value
sourcekitd_variant_functions_set_uid_get_value
sourcekitd_variant_functions_set_data_get_size
sourcekitd_variant_functions_set_data_get_ptr
sourcekitd_plugin_initialize_is_client_only
sourcekitd_plugin_initialize_custom_buffer_start
sourcekitd_plugin_initialize_uid_get_from_cstr
sourcekitd_plugin_initialize_uid_get_string_ptr
sourcekitd_plugin_initialize_register_request_handler
sourcekitd_plugin_initialize_register_custom_buffer
sourcekitd_register_plugin_path
sourcekitd_load_client_plugins

View File

@@ -341,7 +341,6 @@ static void getInitializationInfo(xpc_connection_t peer) {
assert(xpc_get_type(reply) == XPC_TYPE_DICTIONARY);
uint64_t Delay = xpc_dictionary_get_uint64(reply, xpc::KeySemaEditorDelay);
xpc_release(reply);
if (Delay != 0) {
llvm::SmallString<4> Buf;
@@ -351,6 +350,23 @@ static void getInitializationInfo(xpc_connection_t peer) {
}
setenv("SOURCEKIT_DELAY_SEMA_EDITOR", Buf.c_str(), /*overwrite=*/1);
}
// Only call once, in case there is a second connection.
static std::once_flag flag;
std::call_once(flag, [reply] {
std::vector<std::string> registeredPlugins;
xpc_object_t plugins = xpc_dictionary_get_value(reply, xpc::KeyPlugins);
if (plugins && xpc_get_type(plugins) == XPC_TYPE_ARRAY)
for (size_t i = 0, e = xpc_array_get_count(plugins); i < e; ++i)
registeredPlugins.push_back(xpc_array_get_string(plugins, i));
sourcekitd::PluginInitParams pluginParams(
/*isClientOnly=*/false, sourcekitd::pluginRegisterRequestHandler,
sourcekitd::pluginRegisterCancellationHandler,
sourcekitd::pluginGetOpaqueSwiftIDEInspectionInstance());
sourcekitd::loadPlugins(registeredPlugins, pluginParams);
});
xpc_release(reply);
}
static void sourcekitdServer_event_handler(xpc_connection_t peer) {

View File

@@ -162,11 +162,11 @@ struct CompactVariantFuncs {
static bool
dictionary_apply(sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
void *Buf = (void *)dict.data[1];
size_t Index = dict.data[2];
return T::dictionary_apply(Buf, Index, applier);
return T::dictionary_apply(Buf, Index, applier, context);
}
static VariantFunctions Funcs;
@@ -174,27 +174,30 @@ struct CompactVariantFuncs {
template <typename T>
VariantFunctions CompactVariantFuncs<T>::Funcs = {
get_type,
nullptr/*Annot_array_apply*/,
nullptr/*Annot_array_get_bool*/,
nullptr/*Annot_array_get_count*/,
nullptr/*Annot_array_get_int64*/,
nullptr/*Annot_array_get_string*/,
nullptr/*Annot_array_get_uid*/,
nullptr/*Annot_array_get_value*/,
nullptr/*Annot_bool_get_value*/,
dictionary_apply,
nullptr/*Annot_dictionary_get_bool*/,
nullptr/*Annot_dictionary_get_int64*/,
nullptr/*Annot_dictionary_get_string*/,
nullptr/*Annot_dictionary_get_value*/,
nullptr/*Annot_dictionary_get_uid*/,
nullptr/*Annot_string_get_length*/,
nullptr/*Annot_string_get_ptr*/,
nullptr/*Annot_int64_get_value*/,
nullptr/*Annot_uid_get_value*/,
nullptr/*Annot_data_get_size*/,
nullptr/*Annot_data_get_ptr*/,
get_type,
nullptr /*Annot_array_apply*/,
nullptr /*Annot_array_get_bool*/,
nullptr /*Annot_array_get_double*/,
nullptr /*Annot_array_get_count*/,
nullptr /*Annot_array_get_int64*/,
nullptr /*Annot_array_get_string*/,
nullptr /*Annot_array_get_uid*/,
nullptr /*Annot_array_get_value*/,
nullptr /*Annot_bool_get_value*/,
nullptr /*Annot_double_get_value*/,
dictionary_apply,
nullptr /*Annot_dictionary_get_bool*/,
nullptr /*Annot_dictionary_get_double*/,
nullptr /*Annot_dictionary_get_int64*/,
nullptr /*Annot_dictionary_get_string*/,
nullptr /*Annot_dictionary_get_value*/,
nullptr /*Annot_dictionary_get_uid*/,
nullptr /*Annot_string_get_length*/,
nullptr /*Annot_string_get_ptr*/,
nullptr /*Annot_int64_get_value*/,
nullptr /*Annot_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
};
template <typename T>
@@ -221,29 +224,31 @@ struct CompactArrayFuncs {
template <typename T>
VariantFunctions CompactArrayFuncs<T>::Funcs = {
get_type,
nullptr/*AnnotArray_array_apply*/,
nullptr/*AnnotArray_array_get_bool*/,
array_get_count,
nullptr/*AnnotArray_array_get_int64*/,
nullptr/*AnnotArray_array_get_string*/,
nullptr/*AnnotArray_array_get_uid*/,
array_get_value,
nullptr/*AnnotArray_bool_get_value*/,
nullptr/*AnnotArray_dictionary_apply*/,
nullptr/*AnnotArray_dictionary_get_bool*/,
nullptr/*AnnotArray_dictionary_get_int64*/,
nullptr/*AnnotArray_dictionary_get_string*/,
nullptr/*AnnotArray_dictionary_get_value*/,
nullptr/*AnnotArray_dictionary_get_uid*/,
nullptr/*AnnotArray_string_get_length*/,
nullptr/*AnnotArray_string_get_ptr*/,
nullptr/*AnnotArray_int64_get_value*/,
nullptr/*AnnotArray_uid_get_value*/,
nullptr/*Annot_data_get_size*/,
nullptr/*Annot_data_get_ptr*/,
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
};
}
#endif

View File

@@ -26,6 +26,7 @@ static const char *KeyMsgResponse = "response";
static const char *KeyCancelToken = "cancel_token";
static const char *KeyCancelRequest = "cancel_request";
static const char *KeyDisposeRequestHandle = "dispose_request_handle";
static const char *KeyPlugins = "plugins";
enum class Message {
Initialization,

View File

@@ -14,6 +14,7 @@
#define LLVM_SOURCEKITD_INTERNAL_H
#include "SourceKit/Support/CancellationToken.h"
#include "sourcekitd/plugin.h"
#include "sourcekitd/sourcekitd.h"
#include "llvm/ADT/STLExtras.h"
#include <functional>
@@ -33,11 +34,11 @@ namespace SourceKit {
bool sourcekitd_variant_dictionary_apply_impl(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier);
sourcekitd_variant_dictionary_applier_f_t applier, void *context);
bool sourcekitd_variant_array_apply_impl(
sourcekitd_variant_t array,
llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier);
sourcekitd_variant_t array, sourcekitd_variant_array_applier_f_t applier,
void *context);
namespace sourcekitd {
@@ -47,7 +48,7 @@ using SourceKit::SourceKitCancellationToken;
static const unsigned ProtocolMajorVersion = 1;
static const unsigned ProtocolMinorVersion = 0;
enum class CustomBufferKind {
enum class CustomBufferKind : size_t {
TokenAnnotationsArray,
DeclarationsArray,
DocSupportAnnotationArray,
@@ -58,7 +59,8 @@ enum class CustomBufferKind {
AttributesArray,
ExpressionTypeArray,
VariableTypeArray,
RawData
RawData,
CustomBufferKind_End
};
class ResponseBuilder {
@@ -164,6 +166,10 @@ bool shutdownClient();
void set_interrupted_connection_handler(llvm::function_ref<void()> handler);
/// Register a custom buffer kind. Must be called only during plugin loading.
void pluginRegisterCustomBufferKind(uint64_t kind,
sourcekitd_variant_functions_t funcs);
void printRequestObject(sourcekitd_object_t Obj, llvm::raw_ostream &OS);
void printResponse(sourcekitd_response_t Resp, llvm::raw_ostream &OS);
@@ -185,6 +191,11 @@ static inline sourcekitd_variant_t makeIntVariant(int64_t value) {
static inline sourcekitd_variant_t makeBoolVariant(bool value) {
return {{ 0, value, SOURCEKITD_VARIANT_TYPE_BOOL }};
}
static inline sourcekitd_variant_t makeDoubleVariant(double value) {
uint64_t data;
std::memcpy(&data, &value, sizeof(double));
return {{0, data, SOURCEKITD_VARIANT_TYPE_DOUBLE}};
}
static inline sourcekitd_variant_t makeStringVariant(const char *value) {
return {{ 0, (uintptr_t)value, SOURCEKITD_VARIANT_TYPE_STRING }};
}
@@ -197,33 +208,59 @@ static inline sourcekitd_variant_t makeUIDVariant(sourcekitd_uid_t value) {
///
/// sourcekitd_variant_t contains a pointer to such a structure.
struct VariantFunctions {
sourcekitd_variant_type_t (*get_type)(sourcekitd_variant_t obj);
bool (*array_apply)(
sourcekitd_variant_t array,
llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier);
bool (*array_get_bool)(sourcekitd_variant_t array, size_t index);
size_t (*array_get_count)(sourcekitd_variant_t array);
int64_t (*array_get_int64)(sourcekitd_variant_t array, size_t index);
const char *(*array_get_string)(sourcekitd_variant_t array, size_t index);
sourcekitd_uid_t (*array_get_uid)(sourcekitd_variant_t array, size_t index);
sourcekitd_variant_t (*array_get_value)(sourcekitd_variant_t array, size_t index);
bool (*bool_get_value)(sourcekitd_variant_t obj);
bool (*dictionary_apply)(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier);
bool (*dictionary_get_bool)(sourcekitd_variant_t dict, sourcekitd_uid_t key);
int64_t (*dictionary_get_int64)(sourcekitd_variant_t dict, sourcekitd_uid_t key);
const char *(*dictionary_get_string)(sourcekitd_variant_t dict, sourcekitd_uid_t key);
sourcekitd_variant_t (*dictionary_get_value)(sourcekitd_variant_t dict, sourcekitd_uid_t key);
sourcekitd_uid_t (*dictionary_get_uid)(sourcekitd_variant_t dict, sourcekitd_uid_t key);
size_t (*string_get_length)(sourcekitd_variant_t obj);
const char *(*string_get_ptr)(sourcekitd_variant_t obj);
int64_t (*int64_get_value)(sourcekitd_variant_t obj);
sourcekitd_uid_t (*uid_get_value)(sourcekitd_variant_t obj);
size_t (*data_get_size)(sourcekitd_variant_t obj);
const void *(*data_get_ptr)(sourcekitd_variant_t obj);
sourcekitd_variant_functions_get_type_t get_type;
sourcekitd_variant_functions_array_apply_t array_apply;
sourcekitd_variant_functions_array_get_bool_t array_get_bool;
sourcekitd_variant_functions_array_get_double_t array_get_double;
sourcekitd_variant_functions_array_get_count_t array_get_count;
sourcekitd_variant_functions_array_get_int64_t array_get_int64;
sourcekitd_variant_functions_array_get_string_t array_get_string;
sourcekitd_variant_functions_array_get_uid_t array_get_uid;
sourcekitd_variant_functions_array_get_value_t array_get_value;
sourcekitd_variant_functions_bool_get_value_t bool_get_value;
sourcekitd_variant_functions_double_get_value_t double_get_value;
sourcekitd_variant_functions_dictionary_apply_t dictionary_apply;
sourcekitd_variant_functions_dictionary_get_bool_t dictionary_get_bool;
sourcekitd_variant_functions_dictionary_get_double_t dictionary_get_double;
sourcekitd_variant_functions_dictionary_get_int64_t dictionary_get_int64;
sourcekitd_variant_functions_dictionary_get_string_t dictionary_get_string;
sourcekitd_variant_functions_dictionary_get_value_t dictionary_get_value;
sourcekitd_variant_functions_dictionary_get_uid_t dictionary_get_uid;
sourcekitd_variant_functions_string_get_length_t string_get_length;
sourcekitd_variant_functions_string_get_ptr_t string_get_ptr;
sourcekitd_variant_functions_int64_get_value_t int64_get_value;
sourcekitd_variant_functions_uid_get_value_t uid_get_value;
sourcekitd_variant_functions_data_get_size_t data_get_size;
sourcekitd_variant_functions_data_get_ptr_t data_get_ptr;
};
// Parameters for plugin initialization.
struct PluginInitParams {
bool isClientOnly;
uint64_t customBufferStart = (uint64_t)CustomBufferKind::CustomBufferKind_End;
sourcekitd_uid_get_from_cstr_t uidGetFromCstr = sourcekitd_uid_get_from_cstr;
sourcekitd_uid_get_string_ptr_t uidGetStringPtr =
sourcekitd_uid_get_string_ptr;
std::function<void(sourcekitd_cancellable_request_handler_t)>
registerRequestHandler;
std::function<void(sourcekitd_cancellation_handler_t)>
registerCancellationHandler;
std::function<void(uint64_t, sourcekitd_variant_functions_t)>
registerCustomBuffer;
void *opaqueIDEInspectionInstance;
PluginInitParams(bool isClientOnly,
std::function<void(sourcekitd_cancellable_request_handler_t)>
registerRequestHandler,
std::function<void(sourcekitd_cancellation_handler_t)>
registerCancellationHandler,
void *opaqueIDEInspectionInstance = nullptr);
};
void loadPlugins(llvm::ArrayRef<std::string> registeredPlugins,
PluginInitParams &pluginParams);
VariantFunctions *getPluginVariantFunctions(size_t BufKind);
}
#endif

View File

@@ -89,6 +89,8 @@ public:
OS << Val;
}
void visitDouble(double Val) { OS << Val; }
void visitString(llvm::StringRef Str) {
OS << '\"';
// Avoid raw_ostream's write_escaped, we don't want to escape unicode

View File

@@ -14,6 +14,7 @@
#define LLVM_SOURCEKITD_SERVICE_H
#include "SourceKit/Support/CancellationToken.h"
#include "sourcekitd/plugin.h"
#include "sourcekitd/sourcekitd.h"
#include "llvm/ADT/StringRef.h"
@@ -35,6 +36,22 @@ void initializeService(
/// Shutdown the service.
void shutdownService();
/// Register a custom request handler. Must be called only during plugin
/// loading.
void pluginRegisterRequestHandler(
sourcekitd_cancellable_request_handler_t handler);
/// Register a cancellation handler that will be called when a request is
/// cancelled.
/// This function is called even for cancelled requests that are handled by
/// sourcekitd itself and not the plugin. If the plugin doesn't know the request
/// handle to be cancelled, it should ignore the cancellation request.
/// Must be called only during plugin loading.
void pluginRegisterCancellationHandler(
sourcekitd_cancellation_handler_t handler);
void *pluginGetOpaqueSwiftIDEInspectionInstance();
typedef std::function<void(sourcekitd_response_t)> ResponseReceiver;
void handleRequest(sourcekitd_object_t Request,

View File

@@ -0,0 +1,402 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SOURCEKITD_PLUGIN_H
#define LLVM_SOURCEKITD_PLUGIN_H
#include "sourcekitd/sourcekitd.h"
SOURCEKITD_BEGIN_DECLS
typedef void *sourcekitd_variant_functions_t;
typedef sourcekitd_variant_type_t (*sourcekitd_variant_functions_get_type_t)(
sourcekitd_variant_t obj);
typedef bool (*sourcekitd_variant_functions_array_apply_t)(
sourcekitd_variant_t array, sourcekitd_variant_array_applier_f_t applier,
void *context);
typedef bool (*sourcekitd_variant_functions_array_get_bool_t)(
sourcekitd_variant_t array, size_t index);
typedef double (*sourcekitd_variant_functions_array_get_double_t)(
sourcekitd_variant_t array, size_t index);
typedef size_t (*sourcekitd_variant_functions_array_get_count_t)(
sourcekitd_variant_t array);
typedef int64_t (*sourcekitd_variant_functions_array_get_int64_t)(
sourcekitd_variant_t array, size_t index);
typedef const char *(*sourcekitd_variant_functions_array_get_string_t)(
sourcekitd_variant_t array, size_t index);
typedef sourcekitd_uid_t (*sourcekitd_variant_functions_array_get_uid_t)(
sourcekitd_variant_t array, size_t index);
typedef sourcekitd_variant_t (*sourcekitd_variant_functions_array_get_value_t)(
sourcekitd_variant_t array, size_t index);
typedef bool (*sourcekitd_variant_functions_bool_get_value_t)(
sourcekitd_variant_t obj);
typedef double (*sourcekitd_variant_functions_double_get_value_t)(
sourcekitd_variant_t obj);
typedef bool (*sourcekitd_variant_functions_dictionary_apply_t)(
sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_f_t applier, void *context);
typedef bool (*sourcekitd_variant_functions_dictionary_get_bool_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef double (*sourcekitd_variant_functions_dictionary_get_double_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef int64_t (*sourcekitd_variant_functions_dictionary_get_int64_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef const char *(*sourcekitd_variant_functions_dictionary_get_string_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef sourcekitd_variant_t (
*sourcekitd_variant_functions_dictionary_get_value_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef sourcekitd_uid_t (*sourcekitd_variant_functions_dictionary_get_uid_t)(
sourcekitd_variant_t dict, sourcekitd_uid_t key);
typedef size_t (*sourcekitd_variant_functions_string_get_length_t)(
sourcekitd_variant_t obj);
typedef const char *(*sourcekitd_variant_functions_string_get_ptr_t)(
sourcekitd_variant_t obj);
typedef int64_t (*sourcekitd_variant_functions_int64_get_value_t)(
sourcekitd_variant_t obj);
typedef sourcekitd_uid_t (*sourcekitd_variant_functions_uid_get_value_t)(
sourcekitd_variant_t obj);
typedef size_t (*sourcekitd_variant_functions_data_get_size_t)(
sourcekitd_variant_t obj);
typedef const void *(*sourcekitd_variant_functions_data_get_ptr_t)(
sourcekitd_variant_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_variant_functions_t
sourcekitd_variant_functions_create();
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_get_type(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_get_type_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_apply(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_apply_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_bool(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_bool_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_double(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_double_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_count(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_count_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_int64(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_int64_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_string(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_string_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_uid(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_uid_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_array_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_bool_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_bool_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_double_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_double_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_apply(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_apply_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_bool(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_bool_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_double(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_double_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_int64(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_int64_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_string(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_string_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_dictionary_get_uid(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_uid_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_string_get_length(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_string_get_length_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_string_get_ptr(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_string_get_ptr_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_int64_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_int64_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_uid_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_uid_get_value_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_data_get_size(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_data_get_size_t f);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_variant_functions_set_data_get_ptr(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_data_get_ptr_t f);
#if SOURCEKITD_HAS_BLOCKS
/// Legacy request handler predating cancellation support. Should be removed
/// when all clients have migrated to sourcekitd_cancellable_request_handler_t.
typedef bool (^sourcekitd_request_handler_t)(sourcekitd_object_t,
void (^)(sourcekitd_response_t));
/// Handle the request specified by the \c sourcekitd_object_t and keep track
/// of it using the \c sourcekitd_request_handle_t. If the cancellation handler
/// specified by \c sourcekitd_plugin_initialize_register_cancellation_handler
/// is called with the this request handle, the request should be cancelled.
typedef bool (^sourcekitd_cancellable_request_handler_t)(
sourcekitd_object_t, sourcekitd_request_handle_t,
void (^)(sourcekitd_response_t));
typedef void (^sourcekitd_cancellation_handler_t)(sourcekitd_request_handle_t);
typedef sourcekitd_uid_t (*sourcekitd_uid_get_from_cstr_t)(const char *string);
typedef const char *(*sourcekitd_uid_get_string_ptr_t)(sourcekitd_uid_t);
typedef void *sourcekitd_plugin_initialize_params_t;
typedef void (*sourcekitd_plugin_initialize_t)(
sourcekitd_plugin_initialize_params_t);
typedef void (*sourcekitd_plugin_initialize_2_t)(
sourcekitd_plugin_initialize_params_t, const char *sourcekit_path);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL bool
sourcekitd_plugin_initialize_is_client_only(
sourcekitd_plugin_initialize_params_t);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL uint64_t
sourcekitd_plugin_initialize_custom_buffer_start(
sourcekitd_plugin_initialize_params_t);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL sourcekitd_uid_get_from_cstr_t
sourcekitd_plugin_initialize_uid_get_from_cstr(
sourcekitd_plugin_initialize_params_t);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL sourcekitd_uid_get_string_ptr_t
sourcekitd_plugin_initialize_uid_get_string_ptr(
sourcekitd_plugin_initialize_params_t);
/// Legacy registration of request handlers predating cancellation support.
/// Should be removed when all clients have migrated to cancellable request
/// handlers.
SOURCEKITD_DEPRECATED(
"Use sourcekitd_plugin_initialize_register_cancellable_request_handler "
"instead")
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_plugin_initialize_register_request_handler(
sourcekitd_plugin_initialize_params_t, sourcekitd_request_handler_t);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_plugin_initialize_register_cancellable_request_handler(
sourcekitd_plugin_initialize_params_t,
sourcekitd_cancellable_request_handler_t);
/// Adds a function that will be called when a request is cancelled.
/// The cancellation handler is called even for cancelled requests that are
/// handled by sourcekitd itself and not the plugin. If the plugin doesn't know
/// the request handle to be cancelled, it should ignore the cancellation
/// request.
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_plugin_initialize_register_cancellation_handler(
sourcekitd_plugin_initialize_params_t,
sourcekitd_cancellation_handler_t);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_plugin_initialize_register_custom_buffer(
sourcekitd_plugin_initialize_params_t, uint64_t kind,
sourcekitd_variant_functions_t funcs);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void *
sourcekitd_plugin_initialize_get_swift_ide_inspection_instance(
sourcekitd_plugin_initialize_params_t);
#endif // SOURCEKITD_HAS_BLOCKS
//============================================================================//
// Request
//============================================================================//
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_variant_type_t
sourcekitd_request_get_type(sourcekitd_object_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL2 SOURCEKITD_WARN_RESULT sourcekitd_object_t
sourcekitd_request_dictionary_get_value(sourcekitd_object_t dict,
sourcekitd_uid_t key);
/// The underlying C string for the specified key. NULL if the value for the
/// specified key is not a C string value or if there is no value for the
/// specified key.
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL SOURCEKITD_WARN_RESULT const char *
sourcekitd_request_dictionary_get_string(sourcekitd_object_t dict,
sourcekitd_uid_t key);
/// The underlying \c int64 value for the specified key. 0 if the
/// value for the specified key is not an integer value or if there is no
/// value for the specified key.
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL SOURCEKITD_WARN_RESULT int64_t
sourcekitd_request_dictionary_get_int64(sourcekitd_object_t dict,
sourcekitd_uid_t key);
/// The underlying \c bool value for the specified key. false if the
/// value for the specified key is not a Boolean value or if there is no
/// value for the specified key.
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL SOURCEKITD_WARN_RESULT bool
sourcekitd_request_dictionary_get_bool(sourcekitd_object_t dict,
sourcekitd_uid_t key);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL sourcekitd_uid_t
sourcekitd_request_dictionary_get_uid(sourcekitd_object_t dict,
sourcekitd_uid_t key);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT size_t
sourcekitd_request_array_get_count(sourcekitd_object_t array);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_object_t
sourcekitd_request_array_get_value(sourcekitd_object_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT const char *
sourcekitd_request_array_get_string(sourcekitd_object_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT int64_t
sourcekitd_request_array_get_int64(sourcekitd_object_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT bool
sourcekitd_request_array_get_bool(sourcekitd_object_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_uid_t
sourcekitd_request_array_get_uid(sourcekitd_object_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT int64_t
sourcekitd_request_int64_get_value(sourcekitd_object_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT bool
sourcekitd_request_bool_get_value(sourcekitd_object_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT size_t
sourcekitd_request_string_get_length(sourcekitd_object_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT const char *
sourcekitd_request_string_get_ptr(sourcekitd_object_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_uid_t
sourcekitd_request_uid_get_value(sourcekitd_object_t obj);
//============================================================================//
// Response
//============================================================================//
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 sourcekitd_response_t
sourcekitd_response_retain(sourcekitd_response_t object);
SOURCEKITD_PUBLIC
sourcekitd_response_t sourcekitd_response_error_create(sourcekitd_error_t kind,
const char *description);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_response_t
sourcekitd_response_dictionary_create(const sourcekitd_uid_t *keys,
const sourcekitd_response_t *values,
size_t count);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_response_dictionary_set_value(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_response_t value);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_response_dictionary_set_string(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *string);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_response_dictionary_set_stringbuf(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *buf, size_t length);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL2 void
sourcekitd_response_dictionary_set_int64(sourcekitd_response_t dict,
sourcekitd_uid_t key, int64_t val);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL2 void
sourcekitd_response_dictionary_set_bool(sourcekitd_response_t dict,
sourcekitd_uid_t key, bool val);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL2 void
sourcekitd_response_dictionary_set_double(sourcekitd_response_t dict,
sourcekitd_uid_t key, double val);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_response_dictionary_set_uid(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_uid_t uid);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT sourcekitd_response_t
sourcekitd_response_array_create(const sourcekitd_response_t *objects,
size_t count);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL3 void
sourcekitd_response_array_set_value(sourcekitd_response_t array, size_t index,
sourcekitd_response_t value);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL3 void
sourcekitd_response_array_set_string(sourcekitd_response_t array, size_t index,
const char *string);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL3 void
sourcekitd_response_array_set_stringbuf(sourcekitd_response_t array,
size_t index, const char *buf,
size_t length);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 void
sourcekitd_response_array_set_int64(sourcekitd_response_t array, size_t index,
int64_t val);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 void
sourcekitd_response_array_set_double(sourcekitd_response_t array, size_t index,
double val);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL1 SOURCEKITD_NONNULL3 void
sourcekitd_response_array_set_uid(sourcekitd_response_t array, size_t index,
sourcekitd_uid_t uid);
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL void
sourcekitd_response_dictionary_set_custom_buffer(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const void *ptr, size_t size);
SOURCEKITD_END_DECLS
#endif

View File

@@ -25,7 +25,7 @@
/// The policy about the sourcekitd API is to keep it source and ABI compatible,
/// thus SOURCEKITD_VERSION_MAJOR is expected to remain stable.
#define SOURCEKITD_VERSION_MAJOR 0
#define SOURCEKITD_VERSION_MINOR 4
#define SOURCEKITD_VERSION_MINOR 5
#define SOURCEKITD_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -89,6 +89,22 @@
SOURCEKITD_BEGIN_DECLS
/// Register plugin paths.
///
/// This must be called before 'sourcekitd_initialize()' or
/// 'sourcekitd_load_client_plugins()'.
SOURCEKITD_PUBLIC void
sourcekitd_register_plugin_path(const char *clientPlugin,
const char *servicePlugin);
/// Load and initialzie registered client plugins.
///
/// NOTE: This function is called implicitly by 'sourcekitd_initialize()'. Only
/// clients that cannot call 'sourcekitd_initialize()' should need to call this
/// directly. Also, all clients must register the same plugins in the same
/// order.
SOURCEKITD_PUBLIC void sourcekitd_load_client_plugins(void);
/// Initializes structures needed across the rest of the sourcekitd API.
///
/// Must be called before any other sourcekitd call.
@@ -312,8 +328,7 @@ typedef enum {
SOURCEKITD_VARIANT_TYPE_STRING = 4,
SOURCEKITD_VARIANT_TYPE_UID = 5,
SOURCEKITD_VARIANT_TYPE_BOOL = 6,
// Reserved for future addition
// SOURCEKITD_VARIANT_TYPE_DOUBLE = 7,
SOURCEKITD_VARIANT_TYPE_DOUBLE = 7,
SOURCEKITD_VARIANT_TYPE_DATA = 8,
} sourcekitd_variant_type_t;
@@ -389,6 +404,13 @@ bool
sourcekitd_variant_dictionary_get_bool(sourcekitd_variant_t dict,
sourcekitd_uid_t key);
/// The underlying \c double value for the specified key. 0.0 if the
/// value for the specified key is not a double value or if there is no
/// value for the specified key.
SOURCEKITD_PUBLIC SOURCEKITD_NONNULL_ALL SOURCEKITD_WARN_RESULT double
sourcekitd_variant_dictionary_get_double(sourcekitd_variant_t dict,
sourcekitd_uid_t key);
/// The underlying \c sourcekitd_uid_t value for the specified key. NULL if the
/// value for the specified key is not a uid value or if there is no
/// value for the specified key.
@@ -460,6 +482,9 @@ SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT
bool
sourcekitd_variant_array_get_bool(sourcekitd_variant_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT double
sourcekitd_variant_array_get_double(sourcekitd_variant_t array, size_t index);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT
sourcekitd_uid_t
sourcekitd_variant_array_get_uid(sourcekitd_variant_t array, size_t index);
@@ -514,6 +539,9 @@ SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT
bool
sourcekitd_variant_bool_get_value(sourcekitd_variant_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT double
sourcekitd_variant_double_get_value(sourcekitd_variant_t obj);
SOURCEKITD_PUBLIC SOURCEKITD_WARN_RESULT
size_t
sourcekitd_variant_string_get_length(sourcekitd_variant_t obj);

View File

@@ -0,0 +1,24 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SOURCEKITDINPROC_INTERNAL_H
#define LLVM_SOURCEKITDINPROC_INTERNAL_H
#include <string>
namespace sourcekitdInProc {
std::string getRuntimeLibPath();
std::string getSwiftExecutablePath();
std::string getDiagnosticDocumentationPath();
} // namespace sourcekitdInProc
#endif

View File

@@ -90,8 +90,8 @@ public:
static bool
dictionary_apply(void *Buf, size_t Index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
CompactArrayReaderTy Reader(Buf);
sourcekitd_uid_t Kind;
@@ -124,11 +124,12 @@ public:
bool NotRecommended = Flags & 0x2;
bool IsSystem = Flags & 0x1;
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) return false; \
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var, context)) \
return false; \
} while (0)
APPLY(KeyKind, UID, Kind);

View File

@@ -56,17 +56,16 @@ public:
Reader.readEntries(Index, Kind, Offset, Length, USR);
}
static bool
apply(sourcekitd_uid_t Kind, unsigned Offset, unsigned Length,
const char *USR,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)>
applier) {
static bool apply(sourcekitd_uid_t Kind, unsigned Offset, unsigned Length,
const char *USR,
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) \
if (!applier(key, var, context)) \
return false; \
} while (0)
@@ -131,10 +130,10 @@ struct CompactVariantFuncs<DeclarationsArray> {
return Fn(key, Kind, Offset, Length, USR);
}
static bool dictionary_apply(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)>
applier) {
static bool
dictionary_apply(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
void *Buf = (void *)dict.data[1];
size_t Index = dict.data[2];
@@ -143,7 +142,8 @@ struct CompactVariantFuncs<DeclarationsArray> {
unsigned Length;
const char *USR;
DeclarationsArray::readElements(Buf, Index, Kind, Offset, Length, USR);
return DeclarationsArray::apply(Kind, Offset, Length, USR, applier);
return DeclarationsArray::apply(Kind, Offset, Length, USR, applier,
context);
}
static int64_t dictionary_get_int64(sourcekitd_variant_t dict,
@@ -171,14 +171,17 @@ VariantFunctions CompactVariantFuncs<DeclarationsArray>::Funcs = {
get_type,
nullptr /*Annot_array_apply*/,
nullptr /*Annot_array_get_bool*/,
nullptr /*Annot_array_get_double*/,
nullptr /*Annot_array_get_count*/,
nullptr /*Annot_array_get_int64*/,
nullptr /*Annot_array_get_string*/,
nullptr /*Annot_array_get_uid*/,
nullptr /*Annot_array_get_value*/,
nullptr /*Annot_bool_get_value*/,
nullptr /*Annot_double_get_value*/,
dictionary_apply,
nullptr /*Annot_dictionary_get_bool*/,
nullptr /*Annot_dictionary_get_double*/,
dictionary_get_int64,
dictionary_get_string,
nullptr /*Annot_dictionary_get_value*/,

View File

@@ -403,7 +403,7 @@ uint64_t DocStructureArrayReader::getHeaderValue(unsigned index) const {
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) \
if (!applier(key, var, context)) \
return false; \
} while (0)
@@ -414,8 +414,8 @@ struct ElementReader {
static bool
dictionary_apply(void *buffer, size_t index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
CompactArrayReaderTy reader(buffer);
sourcekitd_uid_t kind;
@@ -434,8 +434,8 @@ struct InheritedTypeReader {
static bool
dictionary_apply(void *buffer, size_t index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
CompactArrayReaderTy reader(buffer);
const char *value = nullptr;
@@ -451,9 +451,8 @@ struct AttributesReader {
static bool
dictionary_apply(void *buffer, size_t index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
CompactArrayReaderTy reader(buffer);
sourcekitd_uid_t value;
unsigned offset;
@@ -470,8 +469,8 @@ struct AttributesReader {
struct DocStructureReader {
static bool
dictionary_apply(void *buffer, size_t index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
auto reader = DocStructureArrayReader(buffer);
auto node = reader.readStructure(index);
@@ -509,7 +508,7 @@ struct DocStructureReader {
sourcekitd_variant_t var = { \
{(uintptr_t)getVariantFunctionsFor##Kind##Array(), (uintptr_t)Buf, \
Off}}; \
if (!applier(key, var)) \
if (!applier(key, var, context)) \
return false; \
} while (0)
@@ -571,14 +570,17 @@ VariantFunctions DocStructureArrayFuncs::funcs = {
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,

View File

@@ -63,11 +63,11 @@ public:
const char *,
unsigned,
unsigned> CompactArrayReaderTy;
static bool
dictionary_apply(void *Buf, size_t Index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
CompactArrayReaderTy Reader(Buf);
sourcekitd_uid_t Kind;
@@ -83,11 +83,12 @@ public:
Offset,
Length);
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) return false; \
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var, context)) \
return false; \
} while (0)
APPLY(KeyKind, UID, Kind);

View File

@@ -71,15 +71,16 @@ public:
static bool
dictionary_apply(void *buffer, size_t index,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
ExpressionTypeReader reader((char*)buffer);
auto result = reader.getExpression(index);
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) return false; \
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var, context)) \
return false; \
} while (0)
#define APPLY_ARRAY(Kind, Key) \
@@ -87,8 +88,9 @@ public:
sourcekitd_uid_t key = SKDUIDFromUIdent(Key); \
sourcekitd_variant_t var = { \
{(uintptr_t)getVariantFunctionsFor##Kind##Array(), (uintptr_t)buffer, \
index}}; \
if (!applier(key, var)) return false; \
index}}; \
if (!applier(key, var, context)) \
return false; \
} while (0)
APPLY(KeyExpressionOffset, Int, result.ExprOffset);
@@ -128,27 +130,30 @@ struct ProtocolListFuncs {
}// end of anonymous namespace
VariantFunctions ProtocolListFuncs::Funcs = {
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
};
struct ExpressionTypeArrayBuilder::Implementation {
@@ -230,27 +235,30 @@ ExpressionTypeArrayBuilder::createBuffer() {
}
VariantFunctions ExpressionTypeArrayBuilder::Funcs = {
Implementation::get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
Implementation::array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
Implementation::array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
Implementation::get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
Implementation::array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
Implementation::array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
};
VariantFunctions *

View File

@@ -31,27 +31,30 @@ struct RawDataFuncs {
};
VariantFunctions RawDataFuncs::Funcs = {
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*Annot_array_array_get_count*/,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
nullptr /*AnnotArray_array_get_value*/,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
data_get_size,
data_get_ptr,
get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
nullptr /*Annot_array_array_get_count*/,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
nullptr /*AnnotArray_array_get_value*/,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,
nullptr /*AnnotArray_dictionary_get_uid*/,
nullptr /*AnnotArray_string_get_length*/,
nullptr /*AnnotArray_string_get_ptr*/,
nullptr /*AnnotArray_int64_get_value*/,
nullptr /*AnnotArray_uid_get_value*/,
data_get_size,
data_get_ptr,
};
VariantFunctions *sourcekitd::getVariantFunctionsForRawData() {

View File

@@ -81,18 +81,17 @@ public:
IsSystem = LengthAndIsSystem & 0x1;
}
static bool apply(sourcekitd_uid_t Kind,
unsigned Offset,
unsigned Length,
static bool apply(sourcekitd_uid_t Kind, unsigned Offset, unsigned Length,
bool IsSystem,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var)) return false; \
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t var = make##Ty##Variant(Field); \
if (!applier(key, var, context)) \
return false; \
} while (0)
APPLY(KeyKind, UID, Kind);
@@ -162,11 +161,11 @@ struct CompactVariantFuncs<TokenAnnotationsArray> {
return Fn(key, Kind, Offset, Length, IsSystem);
}
static bool
dictionary_apply(sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t,
sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
void *Buf = (void*)dict.data[1];
size_t Index = dict.data[2];
@@ -176,7 +175,8 @@ struct CompactVariantFuncs<TokenAnnotationsArray> {
bool IsSystem;
TokenAnnotationsArray::readElements(Buf, Index,
Kind, Offset, Length, IsSystem);
return TokenAnnotationsArray::apply(Kind, Offset, Length, IsSystem, applier);
return TokenAnnotationsArray::apply(Kind, Offset, Length, IsSystem, applier,
context);
}
static bool dictionary_get_bool(sourcekitd_variant_t dict,
@@ -200,27 +200,30 @@ struct CompactVariantFuncs<TokenAnnotationsArray> {
};
VariantFunctions CompactVariantFuncs<TokenAnnotationsArray>::Funcs = {
get_type,
nullptr/*Annot_array_apply*/,
nullptr/*Annot_array_get_bool*/,
nullptr/*Annot_array_get_count*/,
nullptr/*Annot_array_get_int64*/,
nullptr/*Annot_array_get_string*/,
nullptr/*Annot_array_get_uid*/,
nullptr/*Annot_array_get_value*/,
nullptr/*Annot_bool_get_value*/,
dictionary_apply,
dictionary_get_bool,
dictionary_get_int64,
nullptr/*Annot_dictionary_get_string*/,
nullptr/*Annot_dictionary_get_value*/,
dictionary_get_uid,
nullptr/*Annot_string_get_length*/,
nullptr/*Annot_string_get_ptr*/,
nullptr/*Annot_int64_get_value*/,
nullptr/*Annot_uid_get_value*/,
nullptr/*Annot_data_get_size*/,
nullptr/*Annot_data_get_ptr*/,
get_type,
nullptr /*Annot_array_apply*/,
nullptr /*Annot_array_get_bool*/,
nullptr /*Annot_array_get_double*/,
nullptr /*Annot_array_get_count*/,
nullptr /*Annot_array_get_int64*/,
nullptr /*Annot_array_get_string*/,
nullptr /*Annot_array_get_uid*/,
nullptr /*Annot_array_get_value*/,
nullptr /*Annot_bool_get_value*/,
nullptr /*Annot_double_get_value*/,
dictionary_apply,
dictionary_get_bool,
nullptr /*Annot_dictionary_get_double*/,
dictionary_get_int64,
nullptr /*Annot_dictionary_get_string*/,
nullptr /*Annot_dictionary_get_value*/,
dictionary_get_uid,
nullptr /*Annot_string_get_length*/,
nullptr /*Annot_string_get_ptr*/,
nullptr /*Annot_int64_get_value*/,
nullptr /*Annot_uid_get_value*/,
nullptr /*Annot_data_get_size*/,
nullptr /*Annot_data_get_ptr*/,
};
} // namespace sourcekitd

View File

@@ -62,17 +62,17 @@ public:
const char *readPrintedType(unsigned Offset) { return PrintedTypes + Offset; }
static bool dictionary_apply(
void *Buffer, size_t Index,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)>
Applier) {
static bool
dictionary_apply(void *Buffer, size_t Index,
sourcekitd_variant_dictionary_applier_f_t Applier,
void *Context) {
VariableTypeReader Reader((char *)Buffer);
auto Result = Reader.getVariable(Index);
#define APPLY(K, Ty, Field) \
do { \
sourcekitd_uid_t Key = SKDUIDFromUIdent(K); \
sourcekitd_variant_t Var = make##Ty##Variant(Field); \
if (!Applier(Key, Var)) \
if (!Applier(Key, Var, Context)) \
return false; \
} while (0)
@@ -157,14 +157,17 @@ VariantFunctions VariableTypeArrayBuilder::Funcs = {
Implementation::get_type,
nullptr /*AnnotArray_array_apply*/,
nullptr /*AnnotArray_array_get_bool*/,
nullptr /*AnnotArray_array_get_double*/,
Implementation::array_get_count,
nullptr /*AnnotArray_array_get_int64*/,
nullptr /*AnnotArray_array_get_string*/,
nullptr /*AnnotArray_array_get_uid*/,
Implementation::array_get_value,
nullptr /*AnnotArray_bool_get_value*/,
nullptr /*AnnotArray_double_get_value*/,
nullptr /*AnnotArray_dictionary_apply*/,
nullptr /*AnnotArray_dictionary_get_bool*/,
nullptr /*AnnotArray_dictionary_get_double*/,
nullptr /*AnnotArray_dictionary_get_int64*/,
nullptr /*AnnotArray_dictionary_get_string*/,
nullptr /*AnnotArray_dictionary_get_value*/,

View File

@@ -16,6 +16,7 @@
#include "sourcekitd/RequestResponsePrinterBase.h"
#include "SourceKit/Support/Logging.h"
#include "SourceKit/Support/UIdent.h"
#include "swift/Basic/LoadDynamicLibrary.h"
#include "swift/Basic/StringExtras.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
@@ -27,6 +28,13 @@
#include "llvm/Support/YAMLParser.h"
#include <mutex>
#if defined(_WIN32) && !defined(__CYGWIN__)
#define NOMINMAX
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
using namespace SourceKit;
using namespace sourcekitd;
using llvm::ArrayRef;
@@ -63,6 +71,47 @@ bool sourcekitd::compareDictKeys(UIdent LHS, UIdent RHS) {
return LHSOrder < RHSOrder;
}
namespace {
/// This a near-copy of llvm::function_ref, but that exposes its members
/// publicly so we can efficiently wrap the applier functions below.
template <typename Fn>
class applier_function_ref;
template <typename Ret, typename... Params>
class applier_function_ref<Ret(Params...)> {
public:
Ret (*callback)(Params... params, void *context) = nullptr;
void *context;
template <typename Callable>
static Ret callback_fn(Params... params, void *context) {
return (*reinterpret_cast<Callable *>(context))(
std::forward<Params>(params)...);
}
template <typename Callable>
applier_function_ref(
Callable &&callable,
std::enable_if_t<
!std::is_same<std::remove_cv_t<std::remove_reference_t<Callable>>,
applier_function_ref>::value> * = nullptr)
: callback(callback_fn<typename std::remove_reference<Callable>::type>),
context(reinterpret_cast<void *>(&callable)) {}
Ret operator()(Params... params) const {
return callback(std::forward<Params>(params)..., context);
}
};
} // end anonymous namespace
static bool variant_dictionary_apply(
sourcekitd_variant_t dict,
applier_function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)>
applier) {
return sourcekitd_variant_dictionary_apply_impl(dict, applier.callback,
applier.context);
}
namespace {
template <typename ImplClass,
@@ -83,9 +132,8 @@ public:
case SOURCEKITD_VARIANT_TYPE_DICTIONARY: {
DictMap Dict;
DictMap &DictRef = Dict;
sourcekitd_variant_dictionary_apply_impl(
Obj,
[&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
variant_dictionary_apply(
Obj, [&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
DictRef.push_back({UIdentFromSKDUID(key), value});
return true;
});
@@ -105,6 +153,9 @@ public:
case SOURCEKITD_VARIANT_TYPE_BOOL:
return static_cast<ImplClass*>(this)->visitBool(
sourcekitd_variant_bool_get_value(Obj));
case SOURCEKITD_VARIANT_TYPE_DOUBLE:
return static_cast<ImplClass *>(this)->visitDouble(
sourcekitd_variant_double_get_value(Obj));
case SOURCEKITD_VARIANT_TYPE_STRING: {
size_t Len = sourcekitd_variant_string_get_length(Obj);
const char *Ptr = sourcekitd_variant_string_get_ptr(Obj);
@@ -224,6 +275,82 @@ bool sourcekitd::shutdownClient() {
return true;
}
extern "C" const char __dso_handle[];
static void withCurrentLibraryPath(llvm::function_ref<void(const char *)> body) {
#if defined(_WIN32) && !defined(__CYGWIN__)
char path[MAX_PATH];
HMODULE currentModule = NULL;
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(LPCWSTR) &withCurrentLibraryPath, &currentModule) == 0) {
int error = GetLastError();
LOG_WARN("plugin-loading", "failed to determine current Windows module. Error: " << error);
return body(nullptr);
}
if (GetModuleFileNameA(currentModule, path, sizeof(path)) == 0) {
int error = GetLastError();
LOG_WARN("plugin-loading", "failed to path of current Windows module. Error: " << error);
return body(nullptr);
}
return body(path);
#else
Dl_info dlinfo;
dladdr(__dso_handle, &dlinfo);
return body(dlinfo.dli_fname);
#endif
}
static void loadPlugin(StringRef plugin, PluginInitParams &pluginParams) {
std::string err;
auto *handle = swift::loadLibrary(plugin.str().c_str(), &err);
if (!handle) {
LOG_WARN("plugin-loading",
"failed to load plugin '" << plugin << "': " << err);
return;
}
auto *plugin_init_2 = (sourcekitd_plugin_initialize_2_t)swift::getAddressOfSymbol(
handle, "sourcekitd_plugin_initialize_2");
if (plugin_init_2) {
withCurrentLibraryPath([&](const char *currentLibraryPath) {
plugin_init_2(&pluginParams, currentLibraryPath);
});
return;
}
// Fall back to the legacy sourcekitd_plugin_initialize function.
auto *plugin_init = (sourcekitd_plugin_initialize_t)swift::getAddressOfSymbol(
handle, "sourcekitd_plugin_initialize");
if (plugin_init) {
plugin_init(&pluginParams);
return;
}
LOG_WARN("plugin-loading",
"plugin '"
<< plugin
<< "' missing expected symbol: sourcekitd_plugin_initialize_2 or sourcekitd_plugin_initialize");
}
void sourcekitd::loadPlugins(ArrayRef<std::string> registeredPlugins,
PluginInitParams &pluginParams) {
// Load from environment variable first so that it will override registered
// plugins.
StringRef envPlugins = getenv("SOURCEKIT_PLUGINS");
while (!envPlugins.empty()) {
StringRef plugin;
std::tie(plugin, envPlugins) = envPlugins.split(":");
assert(!plugin.empty());
loadPlugin(plugin, pluginParams);
}
// Load registered plugins.
for (const auto &path : registeredPlugins)
loadPlugin(path, pluginParams);
}
void
sourcekitd_response_description_dump(sourcekitd_response_t resp) {
// Avoid colors here, we don't properly detect that the debug window inside
@@ -319,7 +446,7 @@ sourcekitd_variant_dictionary_get_value(sourcekitd_variant_t dict,
// Default implementation:
// Linear search for the key/value pair via sourcekitd_variant_dictionary_apply.
sourcekitd_variant_t result = makeNullVariant();
sourcekitd_variant_dictionary_apply_impl(
variant_dictionary_apply(
dict, [&](sourcekitd_uid_t curr_key, sourcekitd_variant_t curr_value) {
if (curr_key == key) {
result = curr_value;
@@ -343,6 +470,13 @@ sourcekitd_variant_dictionary_get_string(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_get_value(dict, key));
}
static bool variant_dictionary_applier_block_f(sourcekitd_uid_t key,
sourcekitd_variant_t value,
void *context) {
auto *block = (sourcekitd_variant_dictionary_applier_t *)context;
return (*block)(key, value);
}
int64_t
sourcekitd_variant_dictionary_get_int64(sourcekitd_variant_t dict,
sourcekitd_uid_t key) {
@@ -367,6 +501,17 @@ sourcekitd_variant_dictionary_get_bool(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_get_value(dict, key));
}
double sourcekitd_variant_dictionary_get_double(sourcekitd_variant_t dict,
sourcekitd_uid_t key) {
if (auto fn = VAR_FN(dict, dictionary_get_double))
return fn(dict, key);
// Default implementation:
// Get the value via sourcekitd_variant_dictionary_get_value.
return sourcekitd_variant_double_get_value(
sourcekitd_variant_dictionary_get_value(dict, key));
}
sourcekitd_uid_t
sourcekitd_variant_dictionary_get_uid(sourcekitd_variant_t dict,
sourcekitd_uid_t key) {
@@ -383,16 +528,16 @@ sourcekitd_variant_dictionary_get_uid(sourcekitd_variant_t dict,
bool
sourcekitd_variant_dictionary_apply(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_t applier) {
return sourcekitd_variant_dictionary_apply_impl(dict, applier);
return sourcekitd_variant_dictionary_apply_impl(
dict, variant_dictionary_applier_block_f, &applier);
}
#endif
bool
sourcekitd_variant_dictionary_apply_impl(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
bool sourcekitd_variant_dictionary_apply_impl(
sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_f_t applier, void *context) {
if (auto fn = VAR_FN(dict, dictionary_apply))
return fn(dict, applier);
return fn(dict, applier, context);
// Default implementation:
// Treat as empty container.
@@ -403,11 +548,7 @@ bool
sourcekitd_variant_dictionary_apply_f(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
return sourcekitd_variant_dictionary_apply_impl(
dict,
[&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
return applier(key, value, context);
});
return sourcekitd_variant_dictionary_apply_impl(dict, applier, context);
}
size_t
@@ -461,6 +602,17 @@ sourcekitd_variant_array_get_bool(sourcekitd_variant_t array, size_t index) {
sourcekitd_variant_array_get_value(array, index));
}
double sourcekitd_variant_array_get_double(sourcekitd_variant_t array,
size_t index) {
if (auto fn = VAR_FN(array, array_get_double))
return fn(array, index);
// Default implementation:
// Get the value via sourcekitd_variant_array_get_value.
return sourcekitd_variant_double_get_value(
sourcekitd_variant_array_get_value(array, index));
}
sourcekitd_uid_t
sourcekitd_variant_array_get_uid(sourcekitd_variant_t array, size_t index) {
if (auto fn = VAR_FN(array, array_get_uid))
@@ -472,24 +624,33 @@ sourcekitd_variant_array_get_uid(sourcekitd_variant_t array, size_t index) {
sourcekitd_variant_array_get_value(array, index));
}
static bool variant_array_applier_block_f(size_t index,
sourcekitd_variant_t obj,
void *context) {
auto *block = (sourcekitd_variant_array_applier_t *)context;
return (*block)(index, obj);
}
#if SOURCEKITD_HAS_BLOCKS
bool
sourcekitd_variant_array_apply(sourcekitd_variant_t array,
sourcekitd_variant_array_applier_t applier) {
return sourcekitd_variant_array_apply_impl(array, applier);
return sourcekitd_variant_array_apply_impl(
array, variant_array_applier_block_f, &applier);
}
#endif
bool sourcekitd_variant_array_apply_impl(
sourcekitd_variant_t array,
llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
sourcekitd_variant_t array, sourcekitd_variant_array_applier_f_t applier,
void *context) {
if (auto fn = VAR_FN(array, array_apply))
return fn(array, applier);
return fn(array, applier, context);
// Default implementation:
// Iterate over elements via a for-loop.
for (size_t i = 0, e = sourcekitd_variant_array_get_count(array); i != e; ++i) {
bool Continue = applier(i, sourcekitd_variant_array_get_value(array, i));
bool Continue =
applier(i, sourcekitd_variant_array_get_value(array, i), context);
if (!Continue)
return false;
}
@@ -499,10 +660,7 @@ bool sourcekitd_variant_array_apply_impl(
bool sourcekitd_variant_array_apply_f(
sourcekitd_variant_t array, sourcekitd_variant_array_applier_f_t applier,
void *context) {
return sourcekitd_variant_array_apply_impl(
array, [&](size_t index, sourcekitd_variant_t value) {
return applier(index, value, context);
});
return sourcekitd_variant_array_apply_impl(array, applier, context);
}
int64_t
@@ -525,6 +683,17 @@ sourcekitd_variant_bool_get_value(sourcekitd_variant_t obj) {
return obj.data[1];
}
double sourcekitd_variant_double_get_value(sourcekitd_variant_t obj) {
if (auto fn = VAR_FN(obj, double_get_value))
return fn(obj);
// Default implementation:
// Assume this is a variant encapsulating the basic type.
double result;
std::memcpy(&result, &obj.data[1], sizeof(double));
return result;
}
size_t
sourcekitd_variant_string_get_length(sourcekitd_variant_t obj) {
if (auto fn = VAR_FN(obj, string_get_length))
@@ -767,3 +936,271 @@ void YAMLRequestParser::initError(StringRef Desc, llvm::yaml::Node *Node,
Range.End.getPointer() - Range.Start.getPointer());
Error.append(Text.begin(), Text.end());
}
sourcekitd_variant_functions_t sourcekitd_variant_functions_create() {
auto *vfuncs = new VariantFunctions();
// Zero-initialize.
memset(vfuncs, 0, sizeof(VariantFunctions));
return vfuncs;
}
void sourcekitd_variant_functions_set_get_type(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_get_type_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->get_type = f;
}
void sourcekitd_variant_functions_set_array_apply(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_apply_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_apply = f;
}
void sourcekitd_variant_functions_set_array_get_bool(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_bool_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_bool = f;
}
void sourcekitd_variant_functions_set_array_get_double(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_double_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_double = f;
}
void sourcekitd_variant_functions_set_array_get_count(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_count_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_count = f;
}
void sourcekitd_variant_functions_set_array_get_int64(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_int64_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_int64 = f;
}
void sourcekitd_variant_functions_set_array_get_string(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_string_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_string = f;
}
void sourcekitd_variant_functions_set_array_get_uid(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_uid_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_uid = f;
}
void sourcekitd_variant_functions_set_array_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_array_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->array_get_value = f;
}
void sourcekitd_variant_functions_set_bool_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_bool_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->bool_get_value = f;
}
void sourcekitd_variant_functions_set_double_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_double_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->double_get_value = f;
}
void sourcekitd_variant_functions_set_dictionary_apply(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_apply_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_apply = f;
}
void sourcekitd_variant_functions_set_dictionary_get_bool(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_bool_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_bool = f;
}
void sourcekitd_variant_functions_set_dictionary_get_double(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_double_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_double = f;
}
void sourcekitd_variant_functions_set_dictionary_get_int64(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_int64_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_int64 = f;
}
void sourcekitd_variant_functions_set_dictionary_get_string(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_string_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_string = f;
}
void sourcekitd_variant_functions_set_dictionary_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_value = f;
}
void sourcekitd_variant_functions_set_dictionary_get_uid(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_dictionary_get_uid_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->dictionary_get_uid = f;
}
void sourcekitd_variant_functions_set_string_get_length(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_string_get_length_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->string_get_length = f;
}
void sourcekitd_variant_functions_set_string_get_ptr(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_string_get_ptr_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->string_get_ptr = f;
}
void sourcekitd_variant_functions_set_int64_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_int64_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->int64_get_value = f;
}
void sourcekitd_variant_functions_set_uid_get_value(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_uid_get_value_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->uid_get_value = f;
}
void sourcekitd_variant_functions_set_data_get_size(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_data_get_size_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->data_get_size = f;
}
void sourcekitd_variant_functions_set_data_get_ptr(
sourcekitd_variant_functions_t funcs,
sourcekitd_variant_functions_data_get_ptr_t f) {
auto *vfuncs = static_cast<VariantFunctions *>(funcs);
vfuncs->data_get_ptr = f;
}
bool sourcekitd_plugin_initialize_is_client_only(
sourcekitd_plugin_initialize_params_t _params) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
return params.isClientOnly;
}
uint64_t sourcekitd_plugin_initialize_custom_buffer_start(
sourcekitd_plugin_initialize_params_t _params) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
return params.customBufferStart;
}
sourcekitd_uid_get_from_cstr_t sourcekitd_plugin_initialize_uid_get_from_cstr(
sourcekitd_plugin_initialize_params_t _params) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
return params.uidGetFromCstr;
}
sourcekitd_uid_get_string_ptr_t sourcekitd_plugin_initialize_uid_get_string_ptr(
sourcekitd_plugin_initialize_params_t _params) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
return params.uidGetStringPtr;
}
void sourcekitd_plugin_initialize_register_request_handler(
sourcekitd_plugin_initialize_params_t _params,
sourcekitd_request_handler_t handler) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
auto handler_wrapper =
^bool(sourcekitd_object_t req, sourcekitd_request_handle_t,
void (^resp)(sourcekitd_response_t)) {
return handler(req, resp);
};
params.registerRequestHandler(handler_wrapper);
}
void sourcekitd_plugin_initialize_register_cancellable_request_handler(
sourcekitd_plugin_initialize_params_t _params,
sourcekitd_cancellable_request_handler_t handler) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
params.registerRequestHandler(handler);
}
void sourcekitd_plugin_initialize_register_cancellation_handler(
sourcekitd_plugin_initialize_params_t _params,
sourcekitd_cancellation_handler_t handler) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
params.registerCancellationHandler(handler);
}
void sourcekitd_plugin_initialize_register_custom_buffer(
sourcekitd_plugin_initialize_params_t _params, uint64_t kind,
sourcekitd_variant_functions_t funcs) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
params.registerCustomBuffer(kind, funcs);
}
void *sourcekitd_plugin_initialize_get_swift_ide_inspection_instance(
sourcekitd_plugin_initialize_params_t _params) {
auto &params = *static_cast<sourcekitd::PluginInitParams *>(_params);
return params.opaqueIDEInspectionInstance;
}
PluginInitParams::PluginInitParams(
bool isClientOnly,
std::function<void(sourcekitd_cancellable_request_handler_t)>
registerRequestHandler,
std::function<void(sourcekitd_cancellation_handler_t)>
registerCancellationHandler,
void *opaqueIDEInspectionInstance)
: isClientOnly(isClientOnly) {
assert(isClientOnly || (registerRequestHandler != nullptr &&
registerCancellationHandler != nullptr));
// Note: we pass in registerRequestHandler rather than accessing
// sourcekitd::pluginRegisterRequestHandler so that when constructing
// parameters from the sourcekitd client library it does not pull in all of
// request handling when linking.
if (!isClientOnly) {
this->registerRequestHandler = registerRequestHandler;
this->registerCancellationHandler = registerCancellationHandler;
}
registerCustomBuffer = [this](uint64_t kind,
sourcekitd_variant_functions_t funcs) {
sourcekitd::pluginRegisterCustomBufferKind(kind, funcs);
customBufferStart = std::max(customBufferStart, kind + 1);
};
this->opaqueIDEInspectionInstance = opaqueIDEInspectionInstance;
}
// MARK: Plugin variant functions
// Note: only modified during plugin loading.
static std::vector<VariantFunctions *> PluginVariantFunctions;
VariantFunctions *sourcekitd::getPluginVariantFunctions(size_t BufKind) {
size_t index = BufKind - (size_t)CustomBufferKind::CustomBufferKind_End;
if (index >= PluginVariantFunctions.size() ||
PluginVariantFunctions[index] == nullptr) {
llvm::report_fatal_error(
"unknown custom buffer kind; possible plugin loading failure");
}
return PluginVariantFunctions[index];
}
void sourcekitd::pluginRegisterCustomBufferKind(
uint64_t kind, sourcekitd_variant_functions_t funcs) {
auto index = kind - (uint64_t)CustomBufferKind::CustomBufferKind_End;
if (index < PluginVariantFunctions.size()) {
assert(PluginVariantFunctions[index] == nullptr &&
"overwriting existing buffer");
} else {
PluginVariantFunctions.resize(index + 1);
}
PluginVariantFunctions[index] = static_cast<VariantFunctions *>(funcs);
}

View File

@@ -50,9 +50,11 @@ public:
Int64,
UID,
Bool,
Double,
CustomData,
Error,
};
private:
ObjectKind Kind;
protected:
@@ -78,6 +80,7 @@ public:
virtual std::optional<StringRef> getString() const { return std::nullopt; }
virtual const char *getCString() const { return nullptr; }
virtual bool getBool() const { return false; }
virtual double getDouble() const { return 0.0; }
virtual const void *getDataPtr() const { return nullptr; }
virtual size_t getDataSize() const { return 0; }
};
@@ -101,8 +104,8 @@ public:
return it != Storage.end() ? it->second : nullptr;
}
bool
apply(llvm::function_ref<bool(sourcekitd_uid_t, SKDObjectRef)> Applier) const {
bool apply(
llvm::function_ref<bool(sourcekitd_uid_t, SKDObjectRef)> Applier) const {
for (const auto& kv : Storage) {
if (!Applier(kv.first, kv.second))
return false;
@@ -236,6 +239,31 @@ private:
bool Storage;
};
class SKDDouble : public SKDObject {
public:
SKDDouble(double Value) : SKDObject(ObjectKind::Double), Storage(Value) {}
sourcekitd_variant_type_t getVariantType() const override {
return SOURCEKITD_VARIANT_TYPE_DOUBLE;
}
double getDouble() const override { return Storage; }
static bool classof(const SKDObject *O) {
return O->getKind() == ObjectKind::Double;
}
private:
double Storage;
};
} // end anonymous namespace
static sourcekitd_variant_t variantFromSKDObject(SKDObjectRef Object);
static sourcekitd_variant_t variantFromSKDObjectPtr(const SKDObject *Object);
namespace {
class SKDCustomData: public SKDObject {
public:
SKDCustomData(std::unique_ptr<llvm::MemoryBuffer> MemBuf)
@@ -260,8 +288,10 @@ public:
return SOURCEKITD_VARIANT_TYPE_ARRAY;
case CustomBufferKind::RawData:
return SOURCEKITD_VARIANT_TYPE_DATA;
}
llvm::report_fatal_error("sourcekitd object did not resolve to a known type");
default:
return getPluginVariantFunctions(static_cast<size_t>(getBufferKind()))
->get_type(variantFromSKDObjectPtr(this));
}
}
CustomBufferKind getBufferKind() const {
@@ -480,6 +510,86 @@ sourcekitd_request_dictionary_set_uid(sourcekitd_object_t dict,
static_cast<SKDObject *>(dict)->set(key, new SKDUID(uid));
}
sourcekitd_object_t
sourcekitd_request_dictionary_get_value(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return static_cast<sourcekitd_object_t>(static_cast<SKDObject *>(dict)->get(key).get());
}
const char *sourcekitd_request_dictionary_get_string(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
auto value = static_cast<SKDObject *>(dict)->get(key);
if (!value) {
return nullptr;
}
return value->getCString();
}
int64_t sourcekitd_request_dictionary_get_int64(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return *static_cast<SKDObject *>(dict)->get(key)->getInt64();
}
bool sourcekitd_request_dictionary_get_bool(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return static_cast<SKDObject *>(dict)->get(key)->getBool();
}
sourcekitd_uid_t sourcekitd_request_dictionary_get_uid(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return static_cast<SKDObject *>(dict)->get(key)->getUID();
}
size_t sourcekitd_request_array_get_count(sourcekitd_object_t array) {
return static_cast<SKDObject *>(array)->getCount();
}
sourcekitd_object_t
sourcekitd_request_array_get_value(sourcekitd_object_t array, size_t index) {
return static_cast<sourcekitd_object_t>(static_cast<SKDObject *>(array)->get(index).get());
}
const char *sourcekitd_request_array_get_string(sourcekitd_object_t array,
size_t index) {
return static_cast<SKDObject *>(array)->get(index)->getCString();
}
int64_t sourcekitd_request_array_get_int64(sourcekitd_object_t array,
size_t index) {
return *static_cast<SKDObject *>(array)->get(index)->getInt64();
}
bool sourcekitd_request_array_get_bool(sourcekitd_object_t array,
size_t index) {
return static_cast<SKDObject *>(array)->get(index)->getBool();
}
sourcekitd_uid_t sourcekitd_request_array_get_uid(sourcekitd_object_t array,
size_t index) {
return static_cast<SKDObject *>(array)->get(index)->getUID();
}
int64_t sourcekitd_request_int64_get_value(sourcekitd_object_t obj) {
return *static_cast<SKDObject *>(obj)->getInt64();
}
bool sourcekitd_request_bool_get_value(sourcekitd_object_t obj) {
return static_cast<SKDObject *>(obj)->getBool();
}
size_t sourcekitd_request_string_get_length(sourcekitd_object_t obj) {
return static_cast<SKDString *>(obj)->getString()->size();
}
const char *sourcekitd_request_string_get_ptr(sourcekitd_object_t obj) {
return static_cast<SKDString *>(obj)->getCString();
}
sourcekitd_uid_t sourcekitd_request_uid_get_value(sourcekitd_object_t obj) {
return static_cast<SKDUID *>(obj)->getUID();
}
sourcekitd_object_t
sourcekitd_request_array_create(const sourcekitd_object_t *objects,
size_t count) {
@@ -566,8 +676,6 @@ sourcekitd_response_error_get_description(sourcekitd_response_t obj) {
llvm::report_fatal_error("invalid sourcekitd error object");
}
static sourcekitd_variant_t variantFromSKDObject(SKDObjectRef Object);
sourcekitd_variant_t
sourcekitd_response_get_value(sourcekitd_response_t resp) {
if (sourcekitd_response_is_error(resp))
@@ -815,6 +923,12 @@ sourcekitd::createErrorRequestFailed(StringRef Description) {
Description));
}
sourcekitd_response_t
sourcekitd::createErrorRequestInterrupted(StringRef Description) {
return retained(new SKDError(SOURCEKITD_ERROR_CONNECTION_INTERRUPTED,
Description));
}
sourcekitd_response_t
sourcekitd::createErrorRequestCancelled() {
return retained(new SKDError(SOURCEKITD_ERROR_REQUEST_CANCELLED,
@@ -836,10 +950,11 @@ static sourcekitd_variant_type_t SKDVar_get_type(sourcekitd_variant_t var) {
static bool SKDVar_array_apply(
sourcekitd_variant_t array,
llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
sourcekitd_variant_array_applier_f_t applier,
void *context) {
return dyn_cast<SKDArray>(SKD_OBJ(array))->apply([&](size_t Index,
SKDObjectRef Object){
return applier(Index, variantFromSKDObject(Object));
return applier(Index, variantFromSKDObject(Object), context);
});
}
@@ -847,6 +962,11 @@ static bool SKDVar_array_get_bool(sourcekitd_variant_t array, size_t index) {
return SKD_OBJ(array)->get(index)->getBool();
}
static double SKDVar_array_get_double(sourcekitd_variant_t array,
size_t index) {
return SKD_OBJ(array)->get(index)->getDouble();
}
static size_t SKDVar_array_get_count(sourcekitd_variant_t array) {
return SKD_OBJ(array)->getCount();
}
@@ -874,12 +994,17 @@ static bool SKDVar_bool_get_value(sourcekitd_variant_t obj) {
return SKD_OBJ(obj)->getBool();
}
static double SKDVar_double_get_value(sourcekitd_variant_t obj) {
return SKD_OBJ(obj)->getDouble();
}
static bool SKDVar_dictionary_apply(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
return dyn_cast<SKDDictionary>(SKD_OBJ(dict))->apply([&](sourcekitd_uid_t Key,
SKDObjectRef Object){
return applier(Key, variantFromSKDObject(Object));
return applier(Key, variantFromSKDObject(Object), context);
});
}
@@ -891,6 +1016,14 @@ SKDVar_dictionary_get_bool(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
return false;
}
static double SKDVar_dictionary_get_double(sourcekitd_variant_t dict,
sourcekitd_uid_t key) {
if (auto Object = SKD_OBJ(dict)->get(key)) {
return Object->getDouble();
}
return 0.0;
}
static int64_t
SKDVar_dictionary_get_int64(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
if (auto Object = SKD_OBJ(dict)->get(key)) {
@@ -946,30 +1079,37 @@ static size_t SKDVar_data_get_size(sourcekitd_variant_t obj) {
}
static VariantFunctions SKDVariantFuncs = {
SKDVar_get_type,
SKDVar_array_apply,
SKDVar_array_get_bool,
SKDVar_array_get_count,
SKDVar_array_get_int64,
SKDVar_array_get_string,
SKDVar_array_get_uid,
SKDVar_array_get_value,
SKDVar_bool_get_value,
SKDVar_dictionary_apply,
SKDVar_dictionary_get_bool,
SKDVar_dictionary_get_int64,
SKDVar_dictionary_get_string,
SKDVar_dictionary_get_value,
SKDVar_dictionary_get_uid,
SKDVar_string_get_length,
SKDVar_string_get_ptr,
SKDVar_int64_get_value,
SKDVar_uid_get_value,
SKDVar_data_get_size,
SKDVar_data_get_ptr,
SKDVar_get_type,
SKDVar_array_apply,
SKDVar_array_get_bool,
SKDVar_array_get_double,
SKDVar_array_get_count,
SKDVar_array_get_int64,
SKDVar_array_get_string,
SKDVar_array_get_uid,
SKDVar_array_get_value,
SKDVar_bool_get_value,
SKDVar_double_get_value,
SKDVar_dictionary_apply,
SKDVar_dictionary_get_bool,
SKDVar_dictionary_get_double,
SKDVar_dictionary_get_int64,
SKDVar_dictionary_get_string,
SKDVar_dictionary_get_value,
SKDVar_dictionary_get_uid,
SKDVar_string_get_length,
SKDVar_string_get_ptr,
SKDVar_int64_get_value,
SKDVar_uid_get_value,
SKDVar_data_get_size,
SKDVar_data_get_ptr,
};
static sourcekitd_variant_t variantFromSKDObject(SKDObjectRef Object) {
return variantFromSKDObjectPtr(Object.get());
}
static sourcekitd_variant_t variantFromSKDObjectPtr(const SKDObject *Object) {
if (!Object)
return makeNullVariant();
@@ -1010,8 +1150,159 @@ static sourcekitd_variant_t variantFromSKDObject(SKDObjectRef Object) {
return {{ (uintptr_t)getVariantFunctionsForRawData(),
(uintptr_t)DataObject->getDataPtr(),
(uintptr_t)DataObject->getDataSize() }};
default:
return {{(uintptr_t)getPluginVariantFunctions(
static_cast<size_t>(DataObject->getBufferKind())),
(uintptr_t)DataObject->getDataPtr(),
(uintptr_t)DataObject->getDataSize()}};
}
}
return {{ (uintptr_t)&SKDVariantFuncs, (uintptr_t)Object.get(), 0 }};
return {{(uintptr_t)&SKDVariantFuncs, (uintptr_t)Object, 0}};
}
sourcekitd_response_t
sourcekitd_response_error_create(sourcekitd_error_t kind,
const char *description) {
SKDError *error = new SKDError(kind, description);
return retained(error);
}
sourcekitd_response_t
sourcekitd_response_dictionary_create(const sourcekitd_uid_t *keys,
const sourcekitd_response_t *values,
size_t count) {
// Request and response dictionaries are represented by the same type.
return sourcekitd_request_dictionary_create(keys, values, count);
}
void sourcekitd_response_dictionary_set_value(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_response_t value) {
static_cast<SKDObject *>(dict)->set(key, static_cast<SKDObject *>(value));
}
void sourcekitd_response_dictionary_set_string(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *string) {
static_cast<SKDObject *>(dict)->set(key, new SKDString(std::string(string)));
}
void sourcekitd_response_dictionary_set_stringbuf(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *buf,
size_t length) {
llvm::SmallString<512> SS;
SS += StringRef(buf, length);
sourcekitd_response_dictionary_set_string(dict, key, SS.c_str());
}
void sourcekitd_response_dictionary_set_int64(sourcekitd_response_t dict,
sourcekitd_uid_t key,
int64_t val) {
static_cast<SKDObject *>(dict)->set(key, new SKDInt64(val));
}
void sourcekitd_response_dictionary_set_bool(sourcekitd_response_t dict,
sourcekitd_uid_t key, bool val) {
static_cast<SKDObject *>(dict)->set(key, new SKDBool(val));
}
void sourcekitd_response_dictionary_set_double(sourcekitd_response_t dict,
sourcekitd_uid_t key,
double val) {
static_cast<SKDObject *>(dict)->set(key, new SKDDouble(val));
}
void sourcekitd_response_dictionary_set_uid(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_uid_t uid) {
static_cast<SKDObject *>(dict)->set(key, new SKDUID(uid));
}
sourcekitd_response_t
sourcekitd_response_array_create(const sourcekitd_response_t *objects,
size_t count) {
// Request and response arrays are represented by the same type.
return sourcekitd_request_array_create(objects, count);
}
void sourcekitd_response_array_set_value(sourcekitd_response_t array,
size_t index,
sourcekitd_response_t value) {
static_cast<SKDObject *>(array)->set(index, static_cast<SKDObject *>(value));
}
void sourcekitd_response_array_set_string(sourcekitd_response_t array,
size_t index, const char *string) {
static_cast<SKDObject *>(array)->set(index,
new SKDString(std::string(string)));
}
void sourcekitd_response_array_set_stringbuf(sourcekitd_response_t array,
size_t index, const char *buf,
size_t length) {
llvm::SmallString<512> SS;
SS += StringRef(buf, length);
sourcekitd_response_array_set_string(array, index, SS.c_str());
}
void sourcekitd_response_array_set_int64(sourcekitd_response_t array,
size_t index, int64_t val) {
static_cast<SKDObject *>(array)->set(index, new SKDInt64(val));
}
void sourcekitd_response_array_set_double(sourcekitd_response_t array,
size_t index, double val) {
static_cast<SKDObject *>(array)->set(index, new SKDDouble(val));
}
void sourcekitd_response_array_set_uid(sourcekitd_response_t array,
size_t index, sourcekitd_uid_t uid) {
static_cast<SKDObject *>(array)->set(index, new SKDUID(uid));
}
sourcekitd_response_t sourcekitd_response_retain(sourcekitd_response_t object) {
return retained(static_cast<SKDObject *>(object));
}
sourcekitd_variant_type_t sourcekitd_request_get_type(sourcekitd_object_t obj) {
if (!obj) {
return SOURCEKITD_VARIANT_TYPE_NULL;
}
switch (static_cast<SKDObject *>(obj)->getKind()) {
case SKDObject::ObjectKind::Dictionary:
return SOURCEKITD_VARIANT_TYPE_DICTIONARY;
case SKDObject::ObjectKind::Array:
return SOURCEKITD_VARIANT_TYPE_ARRAY;
case SKDObject::ObjectKind::String:
return SOURCEKITD_VARIANT_TYPE_STRING;
case SKDObject::ObjectKind::Int64:
return SOURCEKITD_VARIANT_TYPE_INT64;
case SKDObject::ObjectKind::UID:
return SOURCEKITD_VARIANT_TYPE_UID;
case SKDObject::ObjectKind::Bool:
return SOURCEKITD_VARIANT_TYPE_BOOL;
case SKDObject::ObjectKind::Double:
return SOURCEKITD_VARIANT_TYPE_DOUBLE;
case SKDObject::ObjectKind::CustomData:
return static_cast<SKDObject *>(obj)->getVariantType();
case SKDObject::ObjectKind::Error:
llvm_unreachable("Should not be part of a request");
}
}
void sourcekitd_response_dictionary_set_custom_buffer(
sourcekitd_response_t dict, sourcekitd_uid_t key, const void *ptr,
size_t size) {
#ifndef NDEBUG
assert(size >= sizeof(uint64_t));
auto bufKind = *(const uint64_t *)ptr;
assert(bufKind >= (uint64_t)CustomBufferKind::CustomBufferKind_End);
#endif
std::unique_ptr<llvm::WritableMemoryBuffer> Buf;
Buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(size);
memcpy(Buf->getBufferStart(), ptr, size);
static_cast<SKDObject *>(dict)->set(key,
new SKDCustomData(std::move(Buf)));
}

View File

@@ -84,7 +84,6 @@ public:
return createKindAndString(Kind::ErrorRequestCancelled, Description);
}
private:
static CustomXPCData createKindAndString(Kind K, StringRef Str) {
llvm::SmallVector<char, 128> Buf;
Buf.push_back((char)K);
@@ -460,6 +459,81 @@ sourcekitd_request_dictionary_set_uid(sourcekitd_object_t dict,
xpc_dictionary_set_uint64(dict, strFromUID(key), uintptr_t(uid));
}
sourcekitd_object_t
sourcekitd_request_dictionary_get_value(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return xpc_dictionary_get_value(dict, strFromUID(key));
}
const char *sourcekitd_request_dictionary_get_string(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return xpc_dictionary_get_string(dict, strFromUID(key));
}
int64_t sourcekitd_request_dictionary_get_int64(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return xpc_dictionary_get_int64(dict, strFromUID(key));
}
bool sourcekitd_request_dictionary_get_bool(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return xpc_dictionary_get_bool(dict, strFromUID(key));
}
sourcekitd_uid_t sourcekitd_request_dictionary_get_uid(sourcekitd_object_t dict,
sourcekitd_uid_t key) {
return (sourcekitd_uid_t)xpc_dictionary_get_uint64(dict, strFromUID(key));
}
size_t sourcekitd_request_array_get_count(sourcekitd_object_t array) {
return xpc_array_get_count(array);
}
sourcekitd_object_t
sourcekitd_request_array_get_value(sourcekitd_object_t array, size_t index) {
return xpc_array_get_value(array, index);
}
const char *sourcekitd_request_array_get_string(sourcekitd_object_t array,
size_t index) {
return xpc_array_get_string(array, index);
}
int64_t sourcekitd_request_array_get_int64(sourcekitd_object_t array,
size_t index) {
return xpc_array_get_int64(array, index);
}
bool sourcekitd_request_array_get_bool(sourcekitd_object_t array,
size_t index) {
return xpc_array_get_bool(array, index);
}
sourcekitd_uid_t sourcekitd_request_array_get_uid(sourcekitd_object_t array,
size_t index) {
return (sourcekitd_uid_t)xpc_array_get_uint64(array, index);
}
int64_t sourcekitd_request_int64_get_value(sourcekitd_object_t obj) {
return xpc_int64_get_value(obj);
}
bool sourcekitd_request_bool_get_value(sourcekitd_object_t obj) {
return xpc_bool_get_value(obj);
}
size_t sourcekitd_request_string_get_length(sourcekitd_object_t obj) {
return xpc_string_get_length(obj);
}
const char *sourcekitd_request_string_get_ptr(sourcekitd_object_t obj) {
return xpc_string_get_string_ptr(obj);
}
sourcekitd_uid_t sourcekitd_request_uid_get_value(sourcekitd_object_t obj) {
return (sourcekitd_uid_t)xpc_uint64_get_value(obj);
}
sourcekitd_object_t
sourcekitd_request_array_create(const sourcekitd_object_t *objects,
size_t count) {
@@ -608,6 +682,8 @@ static sourcekitd_variant_type_t XPCVar_get_type(sourcekitd_variant_t var) {
return SOURCEKITD_VARIANT_TYPE_INT64;
if (type == XPC_TYPE_BOOL)
return SOURCEKITD_VARIANT_TYPE_BOOL;
if (type == XPC_TYPE_DOUBLE)
return SOURCEKITD_VARIANT_TYPE_DOUBLE;
if (type == XPC_TYPE_STRING)
return SOURCEKITD_VARIANT_TYPE_STRING;
// Take over XPC's UINT64 to mean SourceKitD's UID.
@@ -617,32 +693,35 @@ static sourcekitd_variant_type_t XPCVar_get_type(sourcekitd_variant_t var) {
return SOURCEKITD_VARIANT_TYPE_UID;
if (type == XPC_TYPE_DATA) {
switch(CUSTOM_BUF_KIND(obj)) {
case CustomBufferKind::TokenAnnotationsArray:
case CustomBufferKind::DeclarationsArray:
case CustomBufferKind::DocSupportAnnotationArray:
case CustomBufferKind::CodeCompletionResultsArray:
case CustomBufferKind::DocStructureArray:
case CustomBufferKind::InheritedTypesArray:
case CustomBufferKind::DocStructureElementArray:
case CustomBufferKind::AttributesArray:
case CustomBufferKind::ExpressionTypeArray:
case CustomBufferKind::VariableTypeArray:
auto BufKind = (size_t)CUSTOM_BUF_KIND(obj);
switch (BufKind) {
case (size_t)CustomBufferKind::TokenAnnotationsArray:
case (size_t)CustomBufferKind::DeclarationsArray:
case (size_t)CustomBufferKind::DocSupportAnnotationArray:
case (size_t)CustomBufferKind::CodeCompletionResultsArray:
case (size_t)CustomBufferKind::DocStructureArray:
case (size_t)CustomBufferKind::InheritedTypesArray:
case (size_t)CustomBufferKind::DocStructureElementArray:
case (size_t)CustomBufferKind::AttributesArray:
case (size_t)CustomBufferKind::ExpressionTypeArray:
case (size_t)CustomBufferKind::VariableTypeArray:
return SOURCEKITD_VARIANT_TYPE_ARRAY;
case CustomBufferKind::RawData:
case (size_t)CustomBufferKind::RawData:
return SOURCEKITD_VARIANT_TYPE_DATA;
default:
return getPluginVariantFunctions(BufKind)->get_type(
variantFromXPCObject(obj));
}
}
llvm::report_fatal_error("sourcekitd object did not resolve to a known type");
}
static bool XPCVar_array_apply(
sourcekitd_variant_t array,
llvm::function_ref<bool(size_t, sourcekitd_variant_t)> applier) {
return xpc_array_apply(XPC_OBJ(array),
^(size_t index, xpc_object_t obj) {
return applier(index, variantFromXPCObject(obj));
static bool XPCVar_array_apply(sourcekitd_variant_t array,
sourcekitd_variant_array_applier_f_t applier,
void *context) {
return xpc_array_apply(XPC_OBJ(array), ^(size_t index, xpc_object_t obj) {
return applier(index, variantFromXPCObject(obj), context);
});
}
@@ -650,6 +729,11 @@ static bool XPCVar_array_get_bool(sourcekitd_variant_t array, size_t index) {
return xpc_array_get_bool(XPC_OBJ(array), index);
}
static double XPCVar_array_get_double(sourcekitd_variant_t array,
size_t index) {
return xpc_array_get_double(XPC_OBJ(array), index);
}
static size_t XPCVar_array_get_count(sourcekitd_variant_t array) {
return xpc_array_get_count(XPC_OBJ(array));
}
@@ -676,13 +760,19 @@ static bool XPCVar_bool_get_value(sourcekitd_variant_t obj) {
return xpc_bool_get_value(XPC_OBJ(obj));
}
static bool XPCVar_dictionary_apply(
sourcekitd_variant_t dict,
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
return xpc_dictionary_apply(XPC_OBJ(dict),
^(const char *key, xpc_object_t obj) {
return applier(sourcekitd_uid_get_from_cstr(key),variantFromXPCObject(obj));
});
static double XPCVar_double_get_value(sourcekitd_variant_t obj) {
return xpc_double_get_value(XPC_OBJ(obj));
}
static bool
XPCVar_dictionary_apply(sourcekitd_variant_t dict,
sourcekitd_variant_dictionary_applier_f_t applier,
void *context) {
return xpc_dictionary_apply(
XPC_OBJ(dict), ^(const char *key, xpc_object_t obj) {
return applier(sourcekitd_uid_get_from_cstr(key),
variantFromXPCObject(obj), context);
});
}
static bool
@@ -690,6 +780,11 @@ XPCVar_dictionary_get_bool(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
return xpc_dictionary_get_bool(XPC_OBJ(dict), strFromUID(key));
}
static double XPCVar_dictionary_get_double(sourcekitd_variant_t dict,
sourcekitd_uid_t key) {
return xpc_dictionary_get_double(XPC_OBJ(dict), strFromUID(key));
}
static int64_t
XPCVar_dictionary_get_int64(sourcekitd_variant_t dict, sourcekitd_uid_t key) {
return xpc_dictionary_get_int64(XPC_OBJ(dict), strFromUID(key));
@@ -736,29 +831,31 @@ static sourcekitd_uid_t XPCVar_uid_get_value(sourcekitd_variant_t obj) {
return sourcekitd_uid_t(xpc_uint64_get_value(XPC_OBJ(obj)));
}
static VariantFunctions XPCVariantFuncs = {
XPCVar_get_type,
XPCVar_array_apply,
XPCVar_array_get_bool,
XPCVar_array_get_count,
XPCVar_array_get_int64,
XPCVar_array_get_string,
XPCVar_array_get_uid,
XPCVar_array_get_value,
XPCVar_bool_get_value,
XPCVar_dictionary_apply,
XPCVar_dictionary_get_bool,
XPCVar_dictionary_get_int64,
XPCVar_dictionary_get_string,
XPCVar_dictionary_get_value,
XPCVar_dictionary_get_uid,
XPCVar_string_get_length,
XPCVar_string_get_ptr,
XPCVar_int64_get_value,
XPCVar_uid_get_value,
XPCVar_data_get_size,
XPCVar_data_get_ptr,
XPCVar_get_type,
XPCVar_array_apply,
XPCVar_array_get_bool,
XPCVar_array_get_double,
XPCVar_array_get_count,
XPCVar_array_get_int64,
XPCVar_array_get_string,
XPCVar_array_get_uid,
XPCVar_array_get_value,
XPCVar_bool_get_value,
XPCVar_double_get_value,
XPCVar_dictionary_apply,
XPCVar_dictionary_get_bool,
XPCVar_dictionary_get_double,
XPCVar_dictionary_get_int64,
XPCVar_dictionary_get_string,
XPCVar_dictionary_get_value,
XPCVar_dictionary_get_uid,
XPCVar_string_get_length,
XPCVar_string_get_ptr,
XPCVar_int64_get_value,
XPCVar_uid_get_value,
XPCVar_data_get_size,
XPCVar_data_get_ptr,
};
static sourcekitd_variant_t variantFromXPCObject(xpc_object_t obj) {
@@ -766,43 +863,200 @@ static sourcekitd_variant_t variantFromXPCObject(xpc_object_t obj) {
return makeNullVariant();
if (xpc_get_type(obj) == XPC_TYPE_DATA) {
switch(CUSTOM_BUF_KIND(obj)) {
case CustomBufferKind::TokenAnnotationsArray:
auto BufKind = (size_t)CUSTOM_BUF_KIND(obj);
switch (BufKind) {
case (size_t)CustomBufferKind::TokenAnnotationsArray:
return {{ (uintptr_t)getVariantFunctionsForTokenAnnotationsArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::DeclarationsArray:
case (size_t)CustomBufferKind::DeclarationsArray:
return {{(uintptr_t)getVariantFunctionsForDeclarationsArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0}};
case CustomBufferKind::DocSupportAnnotationArray:
case (size_t)CustomBufferKind::DocSupportAnnotationArray:
return {{ (uintptr_t)getVariantFunctionsForDocSupportAnnotationArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::CodeCompletionResultsArray:
case (size_t)CustomBufferKind::CodeCompletionResultsArray:
return {{ (uintptr_t)getVariantFunctionsForCodeCompletionResultsArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::DocStructureArray:
case (size_t)CustomBufferKind::DocStructureArray:
return {{ (uintptr_t)getVariantFunctionsForDocStructureArray(),
(uintptr_t)CUSTOM_BUF_START(obj), ~size_t(0) }};
case CustomBufferKind::InheritedTypesArray:
case (size_t)CustomBufferKind::InheritedTypesArray:
return {{ (uintptr_t)getVariantFunctionsForInheritedTypesArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::DocStructureElementArray:
case (size_t)CustomBufferKind::DocStructureElementArray:
return {{ (uintptr_t)getVariantFunctionsForDocStructureElementArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::AttributesArray:
case (size_t)CustomBufferKind::AttributesArray:
return {{ (uintptr_t)getVariantFunctionsForAttributesArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::ExpressionTypeArray:
case (size_t)CustomBufferKind::ExpressionTypeArray:
return {{ (uintptr_t)getVariantFunctionsForExpressionTypeArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case CustomBufferKind::VariableTypeArray:
case (size_t)CustomBufferKind::VariableTypeArray:
return {{ (uintptr_t)getVariantFunctionsForVariableTypeArray(),
(uintptr_t)CUSTOM_BUF_START(obj), 0 }};
case sourcekitd::CustomBufferKind::RawData:
case (size_t)sourcekitd::CustomBufferKind::RawData:
return {{ (uintptr_t)getVariantFunctionsForRawData(),
(uintptr_t)CUSTOM_BUF_START(obj),
(uintptr_t)CUSTOM_BUF_SIZE(obj) }};
default:
return {{(uintptr_t)getPluginVariantFunctions(BufKind),
(uintptr_t)CUSTOM_BUF_START(obj),
(uintptr_t)CUSTOM_BUF_SIZE(obj)}};
}
}
return {{ (uintptr_t)&XPCVariantFuncs, (uintptr_t)obj, 0 }};
}
sourcekitd_response_t
sourcekitd_response_error_create(sourcekitd_error_t kind,
const char *description) {
CustomXPCData::Kind xpcKind;
switch (kind) {
case SOURCEKITD_ERROR_REQUEST_INVALID:
xpcKind = CustomXPCData::Kind::ErrorRequestInvalid;
break;
case SOURCEKITD_ERROR_REQUEST_FAILED:
xpcKind = CustomXPCData::Kind::ErrorRequestFailed;
break;
case SOURCEKITD_ERROR_CONNECTION_INTERRUPTED:
xpcKind = CustomXPCData::Kind::ErrorRequestInterrupted;
break;
case SOURCEKITD_ERROR_REQUEST_CANCELLED:
xpcKind = CustomXPCData::Kind::ErrorRequestCancelled;
break;
}
return CustomXPCData::createKindAndString(xpcKind, description).getXObj();
}
sourcekitd_response_t
sourcekitd_response_dictionary_create(const sourcekitd_uid_t *keys,
const sourcekitd_response_t *values,
size_t count) {
llvm::SmallVector<const char *, 8> Keys;
Keys.reserve(count);
for (size_t i = 0; i < count; ++i)
Keys.push_back(strFromUID(keys[i]));
return xpc_dictionary_create(Keys.data(), values, count);
}
void sourcekitd_response_dictionary_set_value(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_response_t value) {
xpc_dictionary_set_value(dict, strFromUID(key), value);
}
void sourcekitd_response_dictionary_set_string(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *string) {
xpc_dictionary_set_string(dict, strFromUID(key), string);
}
void sourcekitd_response_dictionary_set_stringbuf(sourcekitd_response_t dict,
sourcekitd_uid_t key,
const char *buf,
size_t length) {
llvm::SmallString<512> SS;
SS += StringRef(buf, length);
sourcekitd_response_dictionary_set_string(dict, key, SS.c_str());
}
void sourcekitd_response_dictionary_set_int64(sourcekitd_response_t dict,
sourcekitd_uid_t key,
int64_t val) {
xpc_dictionary_set_int64(dict, strFromUID(key), val);
}
void sourcekitd_response_dictionary_set_bool(sourcekitd_response_t dict,
sourcekitd_uid_t key, bool val) {
xpc_dictionary_set_bool(dict, strFromUID(key), val);
}
void sourcekitd_response_dictionary_set_double(sourcekitd_response_t dict,
sourcekitd_uid_t key,
double val) {
xpc_dictionary_set_double(dict, strFromUID(key), val);
}
void sourcekitd_response_dictionary_set_uid(sourcekitd_response_t dict,
sourcekitd_uid_t key,
sourcekitd_uid_t uid) {
xpc_dictionary_set_uint64(dict, strFromUID(key), uintptr_t(uid));
}
sourcekitd_response_t
sourcekitd_response_array_create(const sourcekitd_response_t *objects,
size_t count) {
return xpc_array_create(objects, count);
}
void sourcekitd_response_array_set_value(sourcekitd_response_t array,
size_t index,
sourcekitd_response_t value) {
xpc_array_set_value(array, index, value);
}
void sourcekitd_response_array_set_string(sourcekitd_response_t array,
size_t index, const char *string) {
xpc_array_set_string(array, index, string);
}
void sourcekitd_response_array_set_stringbuf(sourcekitd_response_t array,
size_t index, const char *buf,
size_t length) {
llvm::SmallString<512> SS;
SS += StringRef(buf, length);
sourcekitd_response_array_set_string(array, index, SS.c_str());
}
void sourcekitd_response_array_set_int64(sourcekitd_response_t array,
size_t index, int64_t val) {
xpc_array_set_int64(array, index, val);
}
void sourcekitd_response_array_set_double(sourcekitd_response_t array,
size_t index, double val) {
xpc_array_set_double(array, index, val);
}
void sourcekitd_response_array_set_uid(sourcekitd_response_t array,
size_t index, sourcekitd_uid_t uid) {
xpc_array_set_uint64(array, index, uintptr_t(uid));
}
sourcekitd_response_t sourcekitd_response_retain(sourcekitd_response_t object) {
return xpc_retain(object);
}
sourcekitd_variant_type_t sourcekitd_request_get_type(sourcekitd_object_t obj) {
xpc_type_t XType = xpc_get_type(obj);
if (XType == XPC_TYPE_DICTIONARY)
return SOURCEKITD_VARIANT_TYPE_DICTIONARY;
if (XType == XPC_TYPE_ARRAY)
return SOURCEKITD_VARIANT_TYPE_ARRAY;
if (XType == XPC_TYPE_INT64)
return SOURCEKITD_VARIANT_TYPE_INT64;
if (XType == XPC_TYPE_BOOL)
return SOURCEKITD_VARIANT_TYPE_BOOL;
if (XType == XPC_TYPE_UINT64)
return SOURCEKITD_VARIANT_TYPE_UID;
if (XType == XPC_TYPE_STRING)
return SOURCEKITD_VARIANT_TYPE_STRING;
if (XType == XPC_TYPE_NULL)
return SOURCEKITD_VARIANT_TYPE_NULL;
llvm::report_fatal_error("unkown sourcekitd_object_t type");
}
void sourcekitd_response_dictionary_set_custom_buffer(
sourcekitd_response_t dict, sourcekitd_uid_t key, const void *ptr,
size_t size) {
#ifndef NDEBUG
assert(size >= sizeof(uint64_t));
auto bufKind = *(const uint64_t *)ptr;
assert(bufKind >= (uint64_t)CustomBufferKind::CustomBufferKind_End);
#endif
xpc_object_t xdata = xpc_data_create(ptr, size);
xpc_dictionary_set_value(dict, strFromUID(key), xdata);
xpc_release(xdata);
}

View File

@@ -19,6 +19,7 @@
#include "sourcekitd/Service.h"
#include "sourcekitd/TokenAnnotationsArray.h"
#include "sourcekitd/VariableTypeArray.h"
#include "sourcekitd/plugin.h"
#include "SourceKit/Core/Context.h"
#include "SourceKit/Core/LangSupport.h"
@@ -43,6 +44,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/VirtualFileSystem.h"
@@ -51,6 +53,7 @@
#include <optional>
// FIXME: Portability.
#include <Block.h>
#include <dispatch/dispatch.h>
using namespace sourcekitd;
@@ -104,6 +107,53 @@ static void fillDiagnosticInfo(ResponseBuilder::Dictionary ParentElem,
static SourceKit::Context *GlobalCtx = nullptr;
namespace SourceKit {
class PluginSupport {
std::vector<sourcekitd_cancellable_request_handler_t> RequestHandlers;
std::vector<sourcekitd_cancellation_handler_t> CancellationHandlers;
llvm::sys::Mutex Mtx;
public:
~PluginSupport() {
for (auto &Handler : RequestHandlers) {
Block_release(Handler);
}
RequestHandlers.clear();
}
void addRequestHandler(sourcekitd_cancellable_request_handler_t Handler) {
RequestHandlers.push_back(Block_copy(Handler));
}
/// Register a cancellation handler that will be called when a request is
/// cancelled.
void addCancellationHandler(sourcekitd_cancellation_handler_t Handler) {
CancellationHandlers.push_back(Block_copy(Handler));
}
bool handleRequest(sourcekitd_object_t Req,
sourcekitd_request_handle_t Handle, ResponseReceiver Rec) {
auto ReceiverWrapper = ^void(sourcekitd_response_t Response) {
Rec(Response);
};
for (auto &Handler : RequestHandlers) {
if (Handler(Req, Handle, ReceiverWrapper)) {
return true;
}
}
return false;
}
/// Inform all cancellation handlers in the plugins that the request with the
/// given handle has been cancelled.
void cancelRequest(sourcekitd_request_handle_t Handle) {
for (auto &CancellationHandler : CancellationHandlers) {
CancellationHandler(Handle);
}
}
};
} // end namespace SourceKit
// NOTE: if we had a connection context, these stats should move into it.
static Statistic numRequests(UIdentFromSKDUID(KindStatNumRequests),
"# of requests (total)");
@@ -117,9 +167,11 @@ void sourcekitd::initializeService(
INITIALIZE_LLVM();
initializeSwiftModules();
llvm::EnablePrettyStackTrace();
GlobalCtx = new SourceKit::Context(swiftExecutablePath, runtimeLibPath,
diagnosticDocumentationPath,
SourceKit::createSwiftLangSupport);
GlobalCtx = new SourceKit::Context(
swiftExecutablePath, runtimeLibPath, diagnosticDocumentationPath,
SourceKit::createSwiftLangSupport, [](SourceKit::Context &Ctx) {
return std::make_shared<PluginSupport>();
});
auto noteCenter = GlobalCtx->getNotificationCenter();
noteCenter->addDocumentUpdateNotificationReceiver([postNotification](StringRef DocumentName) {
@@ -402,6 +454,9 @@ void sourcekitd::handleRequest(sourcekitd_object_t Req,
}
void sourcekitd::cancelRequest(SourceKitCancellationToken CancellationToken) {
// Inform all plugins that the request has been cancelled, even if the request
// wasn't handled by a plugin.
getGlobalContext().getPlugins()->cancelRequest(CancellationToken);
getGlobalContext().getRequestTracker()->cancel(CancellationToken);
}
@@ -2065,6 +2120,12 @@ void handleRequestImpl(sourcekitd_object_t ReqObj,
ResponseReceiver Rec) {
++numRequests;
if (getGlobalContext().getPlugins()->handleRequest(ReqObj, CancellationToken,
Rec)) {
// Handled by plugin.
return;
}
RequestDict Req(ReqObj);
if (auto SimulateLongRequestDuration =
@@ -4357,3 +4418,19 @@ static void enableCompileNotifications(bool value) {
trace::unregisterConsumer(&compileConsumer);
}
}
void sourcekitd::pluginRegisterRequestHandler(
sourcekitd_cancellable_request_handler_t handler) {
getGlobalContext().getPlugins()->addRequestHandler(handler);
}
void sourcekitd::pluginRegisterCancellationHandler(
sourcekitd_cancellation_handler_t handler) {
getGlobalContext().getPlugins()->addCancellationHandler(handler);
}
void *sourcekitd::pluginGetOpaqueSwiftIDEInspectionInstance() {
return getGlobalContext()
.getSwiftLangSupport()
.getOpaqueSwiftIDEInspectionInstance();
}

View File

@@ -83,6 +83,7 @@ public:
Ctx = std::make_shared<SourceKit::Context>(
getSwiftExecutablePath(), getRuntimeLibPath(),
/*diagnosticDocumentationPath*/ "", SourceKit::createSwiftLangSupport,
[](SourceKit::Context &Ctx){ return nullptr; },
/*dispatchOnMain=*/false);
}

View File

@@ -72,6 +72,7 @@ public:
getRuntimeLibPath(),
/*diagnosticDocumentationPath*/ "",
SourceKit::createSwiftLangSupport,
[](SourceKit::Context &Ctx){ return nullptr; },
/*dispatchOnMain=*/false)) {
INITIALIZE_LLVM();
// This is avoiding destroying \p SourceKit::Context because another

View File

@@ -133,6 +133,7 @@ public:
getRuntimeLibPath(),
/*diagnosticDocumentationPath*/ "",
SourceKit::createSwiftLangSupport,
[](SourceKit::Context &Ctx){ return nullptr; },
/*dispatchOnMain=*/false);
auto localDocUpdState = std::make_shared<DocUpdateMutexState>();
Ctx->getNotificationCenter()->addDocumentUpdateNotificationReceiver(

View File

@@ -14,11 +14,11 @@
# Buildbots for Darwin OSes
#===------------------------------------------------------------------------===#
[preset: mixin_buildbot_install_components]
swift-install-components=back-deployment;compiler;clang-builtin-headers;libexec;stdlib;sdk-overlay;static-mirror-lib;editor-integration;tools;toolchain-tools;testsuite-tools;sourcekit-xpc-service;swift-remote-mirror;swift-remote-mirror-headers
swift-install-components=back-deployment;compiler;clang-builtin-headers;libexec;stdlib;sdk-overlay;static-mirror-lib;editor-integration;tools;toolchain-tools;testsuite-tools;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers
[preset: mixin_buildbot_install_components_with_clang]
swift-install-components=autolink-driver;back-deployment;compiler;clang-resource-dir-symlink;libexec;stdlib;sdk-overlay;static-mirror-lib;toolchain-tools;license;sourcekit-xpc-service;swift-remote-mirror;swift-remote-mirror-headers
swift-install-components=autolink-driver;back-deployment;compiler;clang-resource-dir-symlink;libexec;stdlib;sdk-overlay;static-mirror-lib;toolchain-tools;license;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers
llvm-install-components=llvm-ar;llvm-ranlib;llvm-cov;llvm-profdata;IndexStore;clang;clang-resource-headers;compiler-rt;clangd;dsymutil;LTO;clang-features-file;lld
[preset: mixin_buildbot_trunk_base]
@@ -2986,7 +2986,7 @@ darwin-toolchain-display-name=Swift Development Snapshot
darwin-toolchain-name=swift-DEVELOPMENT-SNAPSHOT
darwin-toolchain-version=3.999.999
llvm-install-components=clang;clang-resource-headers;compiler-rt;libclang;libclang-headers;dsymutil;clang-features-file
swift-install-components=back-deployment;compiler;clang-builtin-headers;stdlib;libexec;sdk-overlay;license;sourcekit-xpc-service;swift-remote-mirror;swift-remote-mirror-headers
swift-install-components=back-deployment;compiler;clang-builtin-headers;stdlib;libexec;sdk-overlay;license;sourcekit-xpc-service;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers
symbols-package=%(symbols_package)s
install-symroot=%(install_symroot)s

View File

@@ -2583,6 +2583,7 @@ function Test-SourceKitLSP {
"-Xswiftc", "-I$($SourceCache)\sourcekit-lsp\Sources\CAtomics\include",
"-Xswiftc", "-I$($SourceCache)\sourcekit-lsp\Sources\CSourcekitd\include",
"-Xlinker", "$(Get-HostProjectBinaryCache SourceKitLSP)\lib\CSourcekitd.lib",
"-Xswiftc", "-I$($SourceCache)\sourcekit-lsp\Sources\CCompletionScoring\include",
"-Xswiftc", "-I$(Get-HostProjectBinaryCache SourceKitLSP)\swift",
"-Xlinker", "-L$(Get-HostProjectBinaryCache SourceKitLSP)\lib"
)
@@ -2596,6 +2597,10 @@ function Test-SourceKitLSP {
# Log with the highest log level to simplify debugging of CI failures.
$env:SOURCEKIT_LSP_LOG_LEVEL="debug"
# The Windows build doesn't build the SourceKit plugins into the SwiftPM build directory (it builds them using CMake).
# Tell the tests where to find the just-built plugins.
$env:SOURCEKIT_LSP_TEST_PLUGIN_PATHS="$($HostArch.ToolchainInstallRoot)\usr\lib"
Build-SPMProject `
-Action TestParallel `
-Src "$SourceCache\sourcekit-lsp" `