Skip to content

Commit e2235e2

Browse files
authored
Merge pull request #78421 from ahoppen/add-sourcekit-plugin
[SourceKit] Add mechanism to load plugins for request handling into SourceKit
2 parents 3e05e0b + c0ad0b6 commit e2235e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3762
-437
lines changed
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_BASIC_LOADDYNAMICLIBRARY_H
14+
#define SWIFT_BASIC_LOADDYNAMICLIBRARY_H
15+
16+
#include <string>
17+
18+
namespace swift {
19+
void *loadLibrary(const char *path, std::string *err);
20+
void *getAddressOfSymbol(void *handle, const char *symbol);
21+
} // end namespace swift
22+
23+
#endif // SWIFT_BASIC_LOADDYNAMICLIBRARY_H

lib/AST/PluginRegistry.cpp

+1-50
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "swift/Basic/Assertions.h"
1616
#include "swift/Basic/Defer.h"
17+
#include "swift/Basic/LoadDynamicLibrary.h"
1718
#include "swift/Basic/LLVM.h"
1819
#include "swift/Basic/Program.h"
1920
#include "swift/Basic/Sandbox.h"
@@ -25,16 +26,6 @@
2526

2627
#include <signal.h>
2728

28-
#if defined(_WIN32)
29-
#define WIN32_LEAN_AND_MEAN
30-
#define NOMINMAX
31-
#include "llvm/Support/ConvertUTF.h"
32-
#include "llvm/Support/Windows/WindowsSupport.h"
33-
#include <windows.h>
34-
#else
35-
#include <dlfcn.h>
36-
#endif
37-
3829
#if HAVE_UNISTD_H
3930
#include <unistd.h>
4031
#elif defined(_WIN32)
@@ -43,46 +34,6 @@
4334

4435
using namespace swift;
4536

46-
namespace {
47-
void *loadLibrary(const char *path, std::string *err);
48-
void *getAddressOfSymbol(void *handle, const char *symbol);
49-
50-
#if defined(_WIN32)
51-
void *loadLibrary(const char *path, std::string *err) {
52-
SmallVector<wchar_t, MAX_PATH> pathUnicode;
53-
if (std::error_code ec = llvm::sys::windows::UTF8ToUTF16(path, pathUnicode)) {
54-
SetLastError(ec.value());
55-
llvm::MakeErrMsg(err, std::string(path) + ": Can't convert to UTF-16");
56-
return nullptr;
57-
}
58-
59-
HMODULE handle = LoadLibraryW(pathUnicode.data());
60-
if (handle == NULL) {
61-
llvm::MakeErrMsg(err, std::string(path) + ": Can't open");
62-
return nullptr;
63-
}
64-
return (void *)handle;
65-
}
66-
67-
void *getAddressOfSymbol(void *handle, const char *symbol) {
68-
return (void *)uintptr_t(GetProcAddress((HMODULE)handle, symbol));
69-
}
70-
71-
#else
72-
void *loadLibrary(const char *path, std::string *err) {
73-
void *handle = ::dlopen(path, RTLD_LAZY | RTLD_LOCAL);
74-
if (!handle)
75-
*err = ::dlerror();
76-
return handle;
77-
}
78-
79-
void *getAddressOfSymbol(void *handle, const char *symbol) {
80-
return ::dlsym(handle, symbol);
81-
}
82-
83-
#endif
84-
} // namespace
85-
8637
PluginRegistry::PluginRegistry() {
8738
dumpMessaging = ::getenv("SWIFT_DUMP_PLUGIN_MESSAGING") != nullptr;
8839
}

lib/Basic/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ add_swift_host_library(swiftBasic STATIC
5858
ParseableOutput.cpp
5959
JSONSerialization.cpp
6060
LangOptions.cpp
61+
LoadDynamicLibrary.cpp
6162
Located.cpp
6263
Mangler.cpp
6364
OutputFileMap.cpp

lib/Basic/LoadDynamicLibrary.cpp

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/Basic/LoadDynamicLibrary.h"
14+
15+
#if defined(_WIN32)
16+
#define WIN32_LEAN_AND_MEAN
17+
#define NOMINMAX
18+
#include "llvm/Support/ConvertUTF.h"
19+
#include "llvm/Support/Windows/WindowsSupport.h"
20+
#include "swift/Basic/LLVM.h"
21+
#include <windows.h>
22+
#else
23+
#include <dlfcn.h>
24+
#endif
25+
26+
#if defined(_WIN32)
27+
void *swift::loadLibrary(const char *path, std::string *err) {
28+
SmallVector<wchar_t, MAX_PATH> pathUnicode;
29+
if (std::error_code ec = llvm::sys::windows::UTF8ToUTF16(path, pathUnicode)) {
30+
SetLastError(ec.value());
31+
llvm::MakeErrMsg(err, std::string(path) + ": Can't convert to UTF-16");
32+
return nullptr;
33+
}
34+
35+
HMODULE handle = LoadLibraryW(pathUnicode.data());
36+
if (handle == NULL) {
37+
llvm::MakeErrMsg(err, std::string(path) + ": Can't open");
38+
return nullptr;
39+
}
40+
return (void *)handle;
41+
}
42+
43+
void *swift::getAddressOfSymbol(void *handle, const char *symbol) {
44+
return (void *)uintptr_t(GetProcAddress((HMODULE)handle, symbol));
45+
}
46+
47+
#else
48+
void *swift::loadLibrary(const char *path, std::string *err) {
49+
void *handle = ::dlopen(path, RTLD_LAZY | RTLD_LOCAL);
50+
if (!handle)
51+
*err = ::dlerror();
52+
return handle;
53+
}
54+
55+
void *swift::getAddressOfSymbol(void *handle, const char *symbol) {
56+
return ::dlsym(handle, symbol);
57+
}
58+
#endif

tools/SourceKit/include/SourceKit/Core/Context.h

+29-22
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,30 @@ namespace llvm {
3131
namespace SourceKit {
3232
class LangSupport;
3333
class NotificationCenter;
34-
35-
class GlobalConfig {
36-
public:
37-
struct Settings {
38-
struct IDEInspectionOptions {
39-
40-
/// Max count of reusing ASTContext for cached IDE inspection.
41-
unsigned MaxASTContextReuseCount = 100;
42-
43-
/// Interval second for checking dependencies in cached IDE inspection.
44-
unsigned CheckDependencyInterval = 5;
45-
} IDEInspectionOpts;
46-
};
47-
48-
private:
49-
Settings State;
50-
mutable llvm::sys::Mutex Mtx;
51-
52-
public:
53-
Settings update(std::optional<unsigned> IDEInspectionMaxASTContextReuseCount,
54-
std::optional<unsigned> IDEInspectionCheckDependencyInterval);
55-
Settings::IDEInspectionOptions getIDEInspectionOpts() const;
34+
class PluginSupport;
35+
36+
class GlobalConfig {
37+
public:
38+
struct Settings {
39+
struct IDEInspectionOptions {
40+
41+
/// Max count of reusing ASTContext for cached IDE inspection.
42+
unsigned MaxASTContextReuseCount = 100;
43+
44+
/// Interval second for checking dependencies in cached IDE inspection.
45+
unsigned CheckDependencyInterval = 5;
46+
} IDEInspectionOpts;
47+
};
48+
49+
private:
50+
Settings State;
51+
mutable llvm::sys::Mutex Mtx;
52+
53+
public:
54+
Settings
55+
update(std::optional<unsigned> IDEInspectionMaxASTContextReuseCount,
56+
std::optional<unsigned> IDEInspectionCheckDependencyInterval);
57+
Settings::IDEInspectionOptions getIDEInspectionOpts() const;
5658
};
5759

5860
/// Keeps track of all requests that are currently in progress and coordinates
@@ -169,13 +171,16 @@ class Context {
169171
std::shared_ptr<NotificationCenter> NotificationCtr;
170172
std::shared_ptr<GlobalConfig> Config;
171173
std::shared_ptr<RequestTracker> ReqTracker;
174+
std::shared_ptr<PluginSupport> Plugins;
172175
std::shared_ptr<SlowRequestSimulator> SlowRequestSim;
173176

174177
public:
175178
Context(StringRef SwiftExecutablePath, StringRef RuntimeLibPath,
176179
StringRef DiagnosticDocumentationPath,
177180
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
178181
LangSupportFactoryFn,
182+
llvm::function_ref<std::shared_ptr<PluginSupport>(Context &)>
183+
PluginSupportFactoryFn,
179184
bool shouldDispatchNotificationsOnMain = true);
180185
~Context();
181186

@@ -192,6 +197,8 @@ class Context {
192197

193198
std::shared_ptr<GlobalConfig> getGlobalConfiguration() { return Config; }
194199

200+
std::shared_ptr<PluginSupport> getPlugins() { return Plugins; }
201+
195202
std::shared_ptr<SlowRequestSimulator> getSlowRequestSimulator() {
196203
return SlowRequestSim;
197204
}

tools/SourceKit/include/SourceKit/Core/LangSupport.h

+2
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,8 @@ class LangSupport {
10241024

10251025
virtual ~LangSupport() { }
10261026

1027+
virtual void *getOpaqueSwiftIDEInspectionInstance() { return nullptr; }
1028+
10271029
virtual void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) {};
10281030

10291031
virtual void dependencyUpdated() {}

tools/SourceKit/lib/Core/Context.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ SourceKit::Context::Context(
4040
StringRef DiagnosticDocumentationPath,
4141
llvm::function_ref<std::unique_ptr<LangSupport>(Context &)>
4242
LangSupportFactoryFn,
43+
llvm::function_ref<std::shared_ptr<PluginSupport>(Context &)>
44+
PluginSupportFactoryFn,
4345
bool shouldDispatchNotificationsOnMain)
4446
: SwiftExecutablePath(SwiftExecutablePath), RuntimeLibPath(RuntimeLibPath),
4547
DiagnosticDocumentationPath(DiagnosticDocumentationPath),
@@ -49,6 +51,7 @@ SourceKit::Context::Context(
4951
SlowRequestSim(new SlowRequestSimulator(ReqTracker)) {
5052
// Should be called last after everything is initialized.
5153
SwiftLang = LangSupportFactoryFn(*this);
54+
Plugins = PluginSupportFactoryFn(*this);
5255
}
5356

5457
SourceKit::Context::~Context() {

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

+4
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ class SwiftLangSupport : public LangSupport {
534534
// LangSupport Interface
535535
//==========================================================================//
536536

537+
void *getOpaqueSwiftIDEInspectionInstance() override {
538+
return IDEInspectionInst.get();
539+
}
540+
537541
void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) override;
538542

539543
void dependencyUpdated() override;

tools/SourceKit/tools/sourcekitd/bin/InProc/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ swift_is_installing_component(sourcekit-inproc SOURCEKIT_INSTALLING_INPROC)
1111

1212
set(sourcekitdInProc_args
1313
sourcekitdInProc.cpp
14+
CodeCompletionSwiftInterop.cpp
1415
LLVM_LINK_COMPONENTS support coverage
1516
)
1617

1718
if (SOURCEKIT_INSTALLING_INPROC)
1819
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
1920
add_sourcekit_framework(sourcekitdInProc
2021
${SOURCEKITD_SOURCE_DIR}/include/sourcekitd/sourcekitd.h
22+
${SOURCEKITD_SOURCE_DIR}/include/sourcekitd/plugin.h
23+
${CMAKE_CURRENT_SOURCE_DIR}/CodeCompletionSwiftInterop.h
2124
${sourcekitdInProc_args}
2225
MODULEMAP module.modulemap
2326
INSTALL_IN_COMPONENT sourcekit-inproc

0 commit comments

Comments
 (0)