Introduce `SourceKitDCore` as the protocol boundary between dylib
lifecycle management and the high-level `SourceKitD` API. Its single
lifecycle entry point, `initializeService(api:notificationCallback:)`,
receives the already-loaded `sourcekitd_api_functions_t` from
`SourceKitD.init(core:)`.
`SourceKitDCoreImpl` is the standard implementation: `init` opens the
dylib; `initializeService` registers any plugin paths, calls
`api.initialize()`, and wires the notification handler; `deinit` calls
`shutdown()` and closes the handle. Pre-initialized conformances
implement `initializeService` as a no-op.
Wire a `sourcekitdCoreInjector` hook through `Hooks` so an embedding
host can return a pre-initialized `SourceKitDCore` for a given toolchain
path, preventing `sourcekitd_initialize()` from being called a second
time.
Declare `SourceKitDCoreForPlugin` at its use sites so each call site
can express the exact deinit behavior it needs: `dlclose` for handles
acquired via `RTLD_NOLOAD`, and `leak` for externally-owned handles.
CMake was previously doing this itself before 4.0, but seems to be
inserting `/usr/bin/*` now. Resolve the `/usr/bin` trampoline ourselves
in a similar fashion to swiftly (but with xcrun).
Resolves rdar://163462990.
The modulo operator associated `0` and `100`, so the computation here was essentially `handle?.numericValue ?? (0 % 100)`, equivalent to `handle?.numericValue ?? 0`, which means that we didn’t acutally perform modulo operations on the numeric value, which means that we would exceed the maximum number of `os_log_t` objects after some time.
rdar://162891887
There is only one real class that implements the `SourceKitD` protocol, so there really isn’t any need for the protocol + class split at all. Unify them to make code simpler to reason about.
We need to jump through a few extra hoops when the SourceKit plugin is located in SourceKit-LSP’s build folder and we are using `sourcekitd_plugin_initialize` instead of `sourcekitd_plugin_initialize_2`.
This adds a sourcekitd plugin that drives the code completion requests. It also includes a `CompletionScoring` module that’s used to rank code completion results based on their contextual match, allowing us to show more relevant code completion results at the top.