Commit Graph

46 Commits

Author SHA1 Message Date
Alex Hoppen
70f9903144 Move semaphore signaling to block main thread until request has received a reply instead of until it has been handled
This was causing the sourcekit-lsp integration test to fail.
2023-09-28 22:28:50 -07:00
Ben Barham
5b8c034f9d Revert "Fix the --sync option of sourcekit-lsp"
This reverts commit ed45b26221.
2023-09-28 15:48:26 -07:00
Alex Hoppen
ed45b26221 Fix the --sync option of sourcekit-lsp
We were waiting for the semaphores outside of the `messageHandlingQueue`, which means that we didn’t actually block the message handling queue until the previous request received a result, effectively rendering `--sync` useless.
2023-09-28 08:28:36 -07:00
Alex Hoppen
351eaa2393 Make SourceKitServer an actor
Unfortuantely, we have a few potential out-of-order exeuction possibilities while we migrate everything else to also be asyncronous. But those should be low-probability issues that we can fix in follow-up commits, so I think it’s fine for now. All of these places are marked with `FIXME: (async)`
2023-09-27 09:48:21 -07:00
Alex Hoppen
0e5d5c9fda Make MessageHandler.handle async
This is the prerequisite for making `SourceKitServer` an actor, which will mean that the `handle` methods will be `async`.

The current paradigm of returning from `handle` once we can guarantee that there’s no out-of-order execution and then returning the actual result via the callback that’s attached to `Request` is a little weird still. I am hoping to change this paradigm to return the actual result and have a callback function that `handle` can call to indicate that it’s ready to accept another message while guaranteeing in-order execution, essentially flipping the role of the return value and the closure callback. But that’s something to be done after the entire stack has been asyncificied.
2023-09-27 09:47:51 -07:00
Alex Hoppen
7c0a910358 Handle messages on a serial queue in Connection
When we switch `SourceKitServer`, `SwiftLanguageServer` etc. to be actors, we can’t rely on them to provide ordering guarantees anymore because Swift concurrency doesn’t provide any ordering guarantees.

What we should thus do, is to handle all messages on a serial queue on the `Connection` level. This queue will be blocked from handling any new messages until a message has been sufficiently handled to avoid out-of-order handling of messages. For sourcekitd, this means that
a request has been sent to sourcekitd and for clangd, this means that we have forwarded the request to clangd.

Note that this serial queue is not the main thread, so we will continue accepting data over stdin, just the handling of those messages is blocked.
2023-09-27 09:47:51 -07:00
Max Desiatov
66f1c0dbf2 Add support for Musl libc with canImport(Musl) checks (#772)
Since Musl is sufficiently different from Glibc (see https://wiki.musl-libc.org/functional-differences-from-glibc.html), it requires a different import, which now should be applied to files that have `import Glibc` in them.

Musl is a low footprint libc that's used in Linux distributions such as Alpine Linux, which allows producing fairly small container images. Additionally, unlike Glibc, musl allows full static linking, meaning apps can be easily distributed to an arbitrary Linux distribution that may have a version of Glibc incompatible with the one that Swift is usually built with or no Glibc installed at all.
2023-07-18 22:51:26 +01:00
Alex Hoppen
66c598430a Remove workaround for SR-16097 to decode Shutdown request
rdar://92254952
2023-01-13 17:04:35 +01:00
Alex Hoppen
ca45a7a62b Return a .serverCancelled error code if the server cancels a request
`.cancelled` should only be returned if the client requested cancellation.
2022-12-05 08:45:36 +01:00
Saleem Abdulrasool
223f98906e LanguageServerProtocolJSONRPC: avoid failing cast on Windows
This error code is poorly mapped on Windows and results in a runtime
failure.  Avoid the cast to improve stability.
2022-09-25 08:53:32 -07:00
Alex Hoppen
20f5387268 Fix a crash on Linux if a ShutdownRequest was sent without params
Workaround for SR-16097 to avoid hitting SR-16095: VSCode will send shutdown requests without a 'params' key. On macOS getting the superDecoder for a non-existent container returns an empty decoder, on Linux it throws `DecodingError.keyNotFound`, causing a crash.

Perform a targeted fix: If we don't have 'params' and the request is a ShutdownRequest, manually create a `ShutdownRequest` without any parameters.

rdar://91288093
2022-04-22 09:47:41 +02:00
Saleem Abdulrasool
fca0cd3913 build: build SourceKit-LSP with static linking
This adjusts the sourcekit-lsp build to use static linking for the
internal libraries.  It is not currently possible to build
SourceKitLSP.dll as that requires re-exporting the interfaces from the
consumed modules.  However, this allows us to reduce the overall size of
the distribution of SourceKit-LSP by ~1 MiB and reduces the
distributed file set.  The values here assume partial static linking of
swift-package-manager, which helps reduce the total size.

Before:

   228,352 BuildServerProtocol.dll
 1,773,056 LanguageServerProtocol.dll
   114,688 LanguageServerProtocolJSONRPC.dll
    49,152 LSPLogging.dll
   262,656 SKCore.dll
    54,784 SKSupport.dll
    80,896 SKSwiftPMWorkspace.dll
   150,528 SourceKitD.dll
   645,632 SourceKitLSP.dll

    70,144 sourcekit-lsp.exe

 3,429,888 bytes

After:

 2,416,640 sourcekit-lsp.exe

 2,416,640 bytes
2022-03-02 08:43:06 -08:00
Saleem Abdulrasool
d888252350 build: force link against dependencies
This will add an additional link request for dispatch and Foundation
libraries.  These are really required on non-Darwin targets, and should
be satisfied either by the library search path or by explicitly
indicating where the dependencies can be found.
2022-02-27 12:10:30 -08:00
Alex Hoppen
ee53f858c5 Globally ignore SIGPIPE on Linux
We receive a `SIGPIPE` if we write to a pipe that points to a crashed process. This in particular happens if the target of a `JSONRPCConnection` has crashed and we try to send it a message.
On Darwin, `DispatchIO` ignores `SIGPIPE` for the pipes handled by it, but that features is not available on Linux.
Instead, globally ignore `SIGPIPE` on Linux to prevent us from crashing if the `JSONRPCConnection`'s target crashes.

Fixes rdar://75580936
2021-03-22 22:40:47 +01:00
Ben Langmuir
bb9560f2e2 Merge pull request #341 from compnerd/handling
Fix the Pipe handling on Windows to be correct
2020-11-02 11:56:06 -08:00
Saleem Abdulrasool
6a275d134c Fix the Pipe handling on Windows to be correct
This actually addresses the real issue that was ignored earlier about
pipes on Windows.  The FileHandle cannot provide a non-owning file
descriptor (the returned file descriptor would need to be explicitly
`_close`'d by the receiver).  Foundation now vends a `_handle` accessor
to the OS primitive handle.  Use this to create the dispatch loop for
messaging.  We now create the JSONRPCConnection from handles on Windows
which actually should help enable running some of the tests on Windows
as well.
2020-11-02 09:55:58 -08:00
Sebastian Fichtner
7a36a51014 Synchronously send error response on message decoding failure (#334)
* Replaces two logs since those don't result in response messages anymore
* Adds a func for sending messages synchronously, to get the two messages out before fatalError
2020-10-16 16:29:46 -07:00
flowtoolz
0427823d74 Log error before fatalError(...) when message decoding fails 2020-10-13 15:33:59 +02:00
Saleem Abdulrasool
b33a5171cc LanguageServerProtocolJSONRPC: make Windows path work
This adjusts the use of Dispatch to build on Windows.  Windows does not
provide `stdout_fileno` and `stderr_fileno`.  However, it is possible to
use `fileno` to get the associated fileno from the descriptor.

Dispatch on Windows does not deal with fd's but rather with handles.
Convert the file descriptor to a handle and pass that off to dispatch.
The handle is a non-owning reference, and should not be closed.
Fortunately, dispatch does not close the handle when the DispatchIO is
closed.
2020-09-29 13:48:06 -07:00
Ben Langmuir
fae2fe85a7 [JSONRPC] Do not exit until outstanding I/O has finished
Specifically, we care that all outstanding **writes** are finished
before we call the close handler, because otherwise we may (a) send
corrupted output during shutdown, or (b) drop notifications and replies
sent during the shutdown process.  The former is a potential issue for
clients that are not robust about parse failures, and the latter is an
issue for reproducibility and robustness during testing/debugging - in
particular, we have some integration tests that send data without
waiting for individual replies and they need to finish outstanding
replies before exiting.

rdar://60159448
2020-03-10 11:16:34 -07:00
Ben Langmuir
37d0a9381a Merge pull request #205 from compnerd/cmake
build: add CMake build system
2019-12-06 15:42:49 -08:00
Saleem Abdulrasool
54d5324613 build: add CMake build system 2019-12-04 16:47:34 -08:00
Alex Hoppen
f167126c8d Fix typo: JSONRPCConnection should be spelled with two 'n' 2019-11-29 10:20:02 -08:00
Ben Langmuir
dfe2a6bc76 [jsonrpc] Move close handler to start
Since the connection and message handler have a reciprocal need to know
about each other, move the closeHandler so that it has the opportunity
to call a method on the message handler if desired.
2019-11-21 11:56:37 -08:00
Ben Langmuir
775e198f77 Rename LSPSupport -> LSPLogging to reflect reduced scope
Ideally we can someday migrate this to something more standard such as
swift-log, and make it explicit how to control logging for the JSONRPC
module.
2019-11-19 11:08:31 -08:00
Ben Langmuir
10ae122f17 Sink Int extension to JSONRPC
This is the only user of this code, and it's not particularly great.
Sink it to reduce dependency surface area.
2019-11-19 10:52:23 -08:00
Ben Langmuir
ec3fd7f940 Sink firstIndex to its only user in JSONRPC
This isn't a particularly good implementation and it only has one user.
Move it down to reduce dependency surface area.
2019-11-19 10:19:09 -08:00
Alex Hoppen
3eafe7851a Make LSPSupport independent of tools-support-core 2019-11-14 15:11:50 -08:00
Alex Hoppen
05ecd26d08 Reorganize the repository into a set of bare LSP modules and SourceKit modules
We will be able to split the LSP modules off later. These LSP modules
will provide the ability to write custom LSP servers and clients in
Swift. The sourcekit-lsp repository will build on top of this new
package to provide an LSP implementation that creates a language server
for Swift and C-based-languages.
2019-11-14 10:35:06 -08:00
Alex Hoppen
4b3c571db6 Eliminate _IndirectConnection and replace it by closure
This allows us to move the semaphore logic out of the message to the connection where it belongs.
2019-11-12 15:04:44 -08:00
Ben Langmuir
3a99dddb98 Fix hang/crash when a write failure occurs
This code was doing a sync dispatch to a queue it was already running
on. Instead, go through the same path as other close calls.  This would
hang, or if you're lucky crash when dispatch detects the issue.
2019-10-17 16:51:34 -07:00
Ben Langmuir
cac8f8d77f [tsan] Fix race on close in JSONRPCConnection 2019-10-10 14:05:49 -07:00
Richard Howell
81c50db7e1 add the workspace/buildTargets request 2019-09-25 14:16:30 -07:00
Ben Langmuir
a5d5d09695 [jsonrpc] Fix race between close() and EOF
We implicitly close the connection when the input file descriptor is
closed, or if it has an error. But we also close things down explicitly
when we see the exit notification. We need to protect against a race
triggering us to call the close handler multiple times. This was
resulting in `sourcekit-lsp` racing to call `exit(0)`, which triggered a
double-free and abort on Linux.
2019-08-23 14:03:47 -07:00
Ben Langmuir
e6fc0f017b [cli] Add --sync option for testing
When testing the sourcekit-lsp binary, it is handy to be able to force
requests to be handled synchronously. This only affects the protocol
layer, not the implementation. This option is hidden from the help text
and should only be used for testing/debugging.
2019-08-22 16:19:36 -07:00
Richard Howell
93982b2f2a messageRegistry -> protocol 2019-08-16 19:18:29 -07:00
Richard Howell
3701f6dcd5 pass in message registry instead of singleton 2019-08-15 15:28:19 -07:00
Ben Langmuir
65b98b383c Remove testable imports of LanguageServerProtocolJSONRPC 2019-08-08 22:22:50 -07:00
Ben Langmuir
ddd096f019 Rename JSONRPCMessageHeader and methods in preparation for making public 2019-08-08 22:14:57 -07:00
Ben Langmuir
119b3fa1cb Rename Message -> JSONRPCMessage in preparation for making it public 2019-08-08 22:06:07 -07:00
Ben Langmuir
40c57c829f Bump swift-tools-version to 5.1
Changes in swiftpm require swift-5.1, so bump our swift-tools-version to
make it explicit. And fix a new deprecation warning.
2019-07-08 07:07:30 -07:00
Abdullah Selek
fcc91d6e84 Add logs on JSONRPCConnection. 2018-12-10 22:02:17 +00:00
Abdullah Selek
e41128e5ff Use Void over () on LanguageServerProtocolJSONRPC. 2018-12-08 18:30:11 +00:00
Joshua Kaplan
e3ade6c50f Use Void over () 2018-12-07 13:29:16 +09:00
Ben Langmuir
048d72b163 Upgrade SwiftPM dependency to master branch
We are tied to using a SwiftPM that matches the toolchain, so upgrade
from 0.3.0 to .branch("master") and add a pins file to manage updating
that dependency.

This was driven by changes that broke loading packages being developed
with newer version of SwiftPM when using the 0.3.0 tag of libSwiftPM.
However, the changes seem to work when going in the other direction, so
using the newer libSwiftPM hasn't caused any known regressions for using
older toolchain versions (not guarantteed and not tested extensively
though).

This fixes using the latest (November 13) toolchain snapshot on macOS.
On Linux there are other issues not specific to LSP.
2018-11-16 15:11:38 -08:00
Ben Langmuir
aabf57a252 Import SourceKit-LSP sources 2018-11-13 15:50:48 -08:00