mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[SourceKit] Add mechanism to load plugins for request handling into SourceKit
This allows us to load plugins into the sourcekitd service to handle requests (currently only used for code completion). This allows us to implement parts of sourcekitd in Swift and outside of the compiler repository, making it easier to iterated on them because the compiler doesn’t need to be rebuilt.
This commit is contained in:
@@ -31,6 +31,7 @@ namespace llvm {
|
||||
namespace SourceKit {
|
||||
class LangSupport;
|
||||
class NotificationCenter;
|
||||
class PluginSupport;
|
||||
|
||||
class GlobalConfig {
|
||||
public:
|
||||
@@ -169,6 +170,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 +178,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 +196,8 @@ public:
|
||||
|
||||
std::shared_ptr<GlobalConfig> getGlobalConfiguration() { return Config; }
|
||||
|
||||
std::shared_ptr<PluginSupport> getPlugins() { return Plugins; }
|
||||
|
||||
std::shared_ptr<SlowRequestSimulator> getSlowRequestSimulator() {
|
||||
return SlowRequestSim;
|
||||
}
|
||||
|
||||
@@ -1024,6 +1024,8 @@ public:
|
||||
|
||||
virtual ~LangSupport() { }
|
||||
|
||||
virtual void *getOpaqueSwiftIDEInspectionInstance() { return nullptr; }
|
||||
|
||||
virtual void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) {};
|
||||
|
||||
virtual void dependencyUpdated() {}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -534,6 +534,10 @@ public:
|
||||
// LangSupport Interface
|
||||
//==========================================================================//
|
||||
|
||||
void *getOpaqueSwiftIDEInspectionInstance() override {
|
||||
return IDEInspectionInst.get();
|
||||
}
|
||||
|
||||
void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) override;
|
||||
|
||||
void dependencyUpdated() override;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,900 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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();
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
@@ -1,5 +1,7 @@
|
||||
framework module sourcekitdInProc {
|
||||
umbrella header "sourcekitd.h"
|
||||
header "plugin.h"
|
||||
header "CodeCompletionSwiftInterop.h"
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
|
||||
@@ -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,85 @@ 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_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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -177,14 +177,17 @@ VariantFunctions CompactVariantFuncs<T>::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*/,
|
||||
nullptr/*Annot_dictionary_get_int64*/,
|
||||
nullptr/*Annot_dictionary_get_string*/,
|
||||
nullptr/*Annot_dictionary_get_value*/,
|
||||
@@ -224,14 +227,17 @@ VariantFunctions CompactArrayFuncs<T>::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*/,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef LLVM_SOURCEKITD_INTERNAL_H
|
||||
#define LLVM_SOURCEKITD_INTERNAL_H
|
||||
|
||||
|
||||
#include "sourcekitd/plugin.h"
|
||||
#include "SourceKit/Support/CancellationToken.h"
|
||||
#include "sourcekitd/sourcekitd.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
@@ -33,11 +35,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 {
|
||||
|
||||
@@ -58,7 +60,8 @@ enum class CustomBufferKind {
|
||||
AttributesArray,
|
||||
ExpressionTypeArray,
|
||||
VariableTypeArray,
|
||||
RawData
|
||||
RawData,
|
||||
CustomBufferKind_End
|
||||
};
|
||||
|
||||
class ResponseBuilder {
|
||||
@@ -164,6 +167,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 +192,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 +209,57 @@ 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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -89,6 +89,10 @@ 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
|
||||
|
||||
@@ -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,
|
||||
|
||||
399
tools/SourceKit/tools/sourcekitd/include/sourcekitd/plugin.h
Normal file
399
tools/SourceKit/tools/sourcekitd/include/sourcekitd/plugin.h
Normal file
@@ -0,0 +1,399 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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);
|
||||
|
||||
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
|
||||
@@ -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,23 @@
|
||||
|
||||
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 +329,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 +405,14 @@ 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 +484,10 @@ 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 +542,10 @@ 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);
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
do { \
|
||||
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
|
||||
sourcekitd_variant_t var = make##Ty##Variant(Field); \
|
||||
if (!applier(key, var)) return false; \
|
||||
if (!applier(key, var, context)) return false; \
|
||||
} while (0)
|
||||
|
||||
APPLY(KeyKind, UID, Kind);
|
||||
|
||||
@@ -59,14 +59,14 @@ public:
|
||||
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) {
|
||||
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)
|
||||
|
||||
@@ -133,8 +133,8 @@ struct CompactVariantFuncs<DeclarationsArray> {
|
||||
|
||||
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];
|
||||
|
||||
@@ -143,7 +143,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 +172,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*/,
|
||||
|
||||
@@ -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*/,
|
||||
|
||||
@@ -66,8 +66,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;
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
do { \
|
||||
sourcekitd_uid_t key = SKDUIDFromUIdent(K); \
|
||||
sourcekitd_variant_t var = make##Ty##Variant(Field); \
|
||||
if (!applier(key, var)) return false; \
|
||||
if (!applier(key, var, context)) return false; \
|
||||
} while (0)
|
||||
|
||||
APPLY(KeyKind, UID, Kind);
|
||||
|
||||
@@ -71,15 +71,15 @@ 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; \
|
||||
if (!applier(key, var, context)) return false; \
|
||||
} while (0)
|
||||
|
||||
#define APPLY_ARRAY(Kind, Key) \
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
sourcekitd_variant_t var = { \
|
||||
{(uintptr_t)getVariantFunctionsFor##Kind##Array(), (uintptr_t)buffer, \
|
||||
index}}; \
|
||||
if (!applier(key, var)) return false; \
|
||||
if (!applier(key, var, context)) return false; \
|
||||
} while (0)
|
||||
|
||||
APPLY(KeyExpressionOffset, Int, result.ExprOffset);
|
||||
@@ -131,14 +131,17 @@ VariantFunctions ProtocolListFuncs::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*/,
|
||||
@@ -233,14 +236,17 @@ VariantFunctions ExpressionTypeArrayBuilder::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*/,
|
||||
|
||||
@@ -34,14 +34,17 @@ VariantFunctions RawDataFuncs::Funcs = {
|
||||
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*/,
|
||||
|
||||
@@ -85,14 +85,14 @@ public:
|
||||
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; \
|
||||
if (!applier(key, var, context)) return false; \
|
||||
} while (0)
|
||||
|
||||
APPLY(KeyKind, UID, Kind);
|
||||
@@ -165,8 +165,8 @@ struct CompactVariantFuncs<TokenAnnotationsArray> {
|
||||
|
||||
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 +176,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,
|
||||
@@ -203,14 +204,17 @@ VariantFunctions CompactVariantFuncs<TokenAnnotationsArray>::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,
|
||||
dictionary_get_bool,
|
||||
nullptr/*Annot_dictionary_get_double*/,
|
||||
dictionary_get_int64,
|
||||
nullptr/*Annot_dictionary_get_string*/,
|
||||
nullptr/*Annot_dictionary_get_value*/,
|
||||
|
||||
@@ -64,15 +64,14 @@ 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) {
|
||||
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 +156,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*/,
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "llvm/Support/YAMLParser.h"
|
||||
#include <mutex>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace SourceKit;
|
||||
using namespace sourcekitd;
|
||||
using llvm::ArrayRef;
|
||||
@@ -63,6 +65,46 @@ 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,7 +125,7 @@ public:
|
||||
case SOURCEKITD_VARIANT_TYPE_DICTIONARY: {
|
||||
DictMap Dict;
|
||||
DictMap &DictRef = Dict;
|
||||
sourcekitd_variant_dictionary_apply_impl(
|
||||
variant_dictionary_apply(
|
||||
Obj,
|
||||
[&](sourcekitd_uid_t key, sourcekitd_variant_t value) {
|
||||
DictRef.push_back({UIdentFromSKDUID(key), value});
|
||||
@@ -105,6 +147,8 @@ 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 +268,45 @@ bool sourcekitd::shutdownClient() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void loadPlugin(StringRef plugin, PluginInitParams &pluginParams) {
|
||||
|
||||
auto *handle = dlopen(plugin.str().c_str(), RTLD_FIRST | RTLD_LAZY);
|
||||
if (!handle) {
|
||||
LOG_WARN("plugin-loading",
|
||||
"failed to load plugin '" << plugin << "': " << dlerror());
|
||||
return;
|
||||
}
|
||||
|
||||
auto *plugin_init = (sourcekitd_plugin_initialize_t)dlsym(
|
||||
handle, "sourcekitd_plugin_initialize");
|
||||
if (!plugin_init) {
|
||||
LOG_WARN("plugin-loading",
|
||||
"plugin '"
|
||||
<< plugin
|
||||
<< "' missing expected symbol: sourcekitd_plugin_initialize");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin_init(&pluginParams);
|
||||
}
|
||||
|
||||
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 +402,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 +426,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 +457,18 @@ 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 +485,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(
|
||||
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) {
|
||||
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 +505,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 +559,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 +581,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 +617,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 +640,18 @@ 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 +894,244 @@ 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.
|
||||
bzero(vfuncs, 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 ¶ms = *static_cast<sourcekitd::PluginInitParams *>(_params);
|
||||
return params.isClientOnly;
|
||||
}
|
||||
|
||||
uint64_t sourcekitd_plugin_initialize_custom_buffer_start(
|
||||
sourcekitd_plugin_initialize_params_t _params) {
|
||||
auto ¶ms = *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 ¶ms = *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 ¶ms = *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 ¶ms = *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 ¶ms = *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 ¶ms = *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 ¶ms = *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 ¶ms = *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;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
Int64,
|
||||
UID,
|
||||
Bool,
|
||||
Double,
|
||||
CustomData,
|
||||
Error,
|
||||
};
|
||||
@@ -78,6 +79,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; }
|
||||
};
|
||||
@@ -236,6 +238,25 @@ 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;
|
||||
};
|
||||
|
||||
class SKDCustomData: public SKDObject {
|
||||
public:
|
||||
SKDCustomData(std::unique_ptr<llvm::MemoryBuffer> MemBuf)
|
||||
@@ -847,6 +868,10 @@ 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,6 +899,10 @@ 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) {
|
||||
@@ -891,6 +920,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)) {
|
||||
@@ -949,14 +986,17 @@ static VariantFunctions SKDVariantFuncs = {
|
||||
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,
|
||||
|
||||
@@ -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) {
|
||||
@@ -596,6 +670,18 @@ sourcekitd_response_get_value(sourcekitd_response_t resp) {
|
||||
((const void*)(((const uint64_t*)xpc_data_get_bytes_ptr(xobj))+1))
|
||||
#define CUSTOM_BUF_SIZE(xobj) (xpc_data_get_length(xobj) - sizeof(uint64_t))
|
||||
|
||||
// Note: only modified during plugin loading.
|
||||
static std::vector<VariantFunctions *> PluginVariantFunctions;
|
||||
|
||||
VariantFunctions *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];
|
||||
}
|
||||
|
||||
static sourcekitd_variant_type_t XPCVar_get_type(sourcekitd_variant_t var) {
|
||||
xpc_object_t obj = XPC_OBJ(var);
|
||||
|
||||
@@ -608,6 +694,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,20 +705,23 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,10 +730,11 @@ static sourcekitd_variant_type_t XPCVar_get_type(sourcekitd_variant_t var) {
|
||||
|
||||
static bool XPCVar_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 xpc_array_apply(XPC_OBJ(array),
|
||||
^(size_t index, xpc_object_t obj) {
|
||||
return applier(index, variantFromXPCObject(obj));
|
||||
return applier(index, variantFromXPCObject(obj), context);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -650,6 +742,10 @@ 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,12 +772,17 @@ static bool XPCVar_bool_get_value(sourcekitd_variant_t obj) {
|
||||
return xpc_bool_get_value(XPC_OBJ(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,
|
||||
llvm::function_ref<bool(sourcekitd_uid_t, sourcekitd_variant_t)> applier) {
|
||||
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));
|
||||
return applier(sourcekitd_uid_get_from_cstr(key),variantFromXPCObject(obj), context);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -690,6 +791,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));
|
||||
@@ -741,14 +847,17 @@ static VariantFunctions XPCVariantFuncs = {
|
||||
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,
|
||||
@@ -766,43 +875,211 @@ 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::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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ public:
|
||||
Ctx = std::make_shared<SourceKit::Context>(
|
||||
getSwiftExecutablePath(), getRuntimeLibPath(),
|
||||
/*diagnosticDocumentationPath*/ "", SourceKit::createSwiftLangSupport,
|
||||
[](SourceKit::Context &Ctx){ return nullptr; },
|
||||
/*dispatchOnMain=*/false);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user