Commit Graph

88 Commits

Author SHA1 Message Date
Alex Hoppen
1d7c27bc4b Adopt MemberImportVisibility 2024-11-05 21:04:01 -08:00
Alex Hoppen
d9132223ba Merge pull request #1799 from ahoppen/input-mirror
Add a logging option to record all notifications received by SoruceKit-LSP
2024-11-01 12:28:31 -07:00
Alex Hoppen
98c44f89eb Add a logging option to record all notifications received by SoruceKit-LSP
This allows us to record the communication between SourceKit-LSP and the editor on a very low level to inspect any transfer issues. It also allows us to record an entire SourceKit-LSP session and replay it using

```
cat /path/to/mirror.log - | path/to/sourcekit-lsp
```
2024-10-31 11:35:13 -07:00
Alex Hoppen
e07a2753fa Fix incorrect log message in JSONRPCConnection
Not all JSON-RPC connections are to build servers. They can also be to clangd.
2024-10-30 13:57:38 -07:00
Alex Hoppen
951e923245 Use withUnsafeFileSystemRepresentation to get the path of a URL on disk
`URL.path` returns forward slashes in the path on Windows (https://github.com/swiftlang/swift-foundation/issues/973) where we expect backslashes. Work around that by defining our own `filePath` property that is backed by `withUnsafeFileSystemRepresentation`, which produces backslashes.

rdar://137963660
2024-10-21 11:12:30 -07:00
Alex Hoppen
e50b4d78e5 Remove elements from outstandingRequests on crash
Otherwise, we can have a retain cycle where the `OutstandingRequest` keeps the `JSONRPCConnection` alive.

Also move the code that handled `outstandingRequests` out of the `Task` because `outstandingRequests` should only be accessed from `queue`.
2024-10-04 17:22:26 -07:00
Alex Hoppen
8cd831b55d Adopt InternalImportsByDefault 2024-09-27 09:17:13 -07:00
Alex Hoppen
e0fba27649 Merge pull request #1645 from ahoppen/extended-logging
Log full options with which SourceKit-LSP is initialized
2024-09-25 14:03:54 -07:00
Alex Hoppen
1fd700b810 Expose all BSP messages used by SourceKit-LSP to BSP servers
The interaction to an out-of-process BSP server still went through the `BuildServerBuildSystem`, which doesn’t forward all messages to the build system and uses the old push-based model for build settings.

If we discover that the BSP server supports the new pull-based build settings model, we now forward all methods to it directly, without going through `BuiltInBuildSystemAdapter`, which has been renamed to `LegacyBuildServerBuildSystem`.

rdar://136106323
rdar://127606323
rdar://126493405
Fixes #1226
Fixes #1173
2024-09-24 22:47:07 -07:00
Alex Hoppen
78b4955d6c Log full initialize request and response
The initialize request and response are often critical to debug issues with editor setups. Log them completely over multiple log messages, instead of truncating them in the normal logging path.
2024-09-23 08:52:19 -07:00
Alex Hoppen
32613f28c5 Log redacted versions of the requests if private logging is disabled
Even if we don’t want to log any sensitive information, we can still log the keys of JSON objects and insensitive values such as integers and booleans.
2024-09-23 08:49:37 -07:00
Alex Hoppen
2721782115 When a JSON-RPC connection is closed, send an error response to all outstanding requests 2024-09-23 08:43:48 -07:00
Max Desiatov
fd1a472653 Revert "When a JSON-RPC connection is closed, send an error response to all outstanding requests" (#1706)
Reverts swiftlang/sourcekit-lsp#1688

This seems to be breaking toolchain builds:

```
JSONRPCConnection.swift:168:35: error: reference to property 'outstandingRequests' in closure
requires explicit use of 'self' to make capture semantics explicit
        for outstandingRequest in outstandingRequests.values {
```

https://ci.swift.org/job/swift-PR-toolchain-macos/1519/console
2024-09-23 10:28:20 +01:00
Alex Hoppen
8cdda3272b When a JSON-RPC connection is closed, send an error response to all outstanding requests 2024-09-19 12:52:46 -07:00
Alex Hoppen
099c8caced Use firstRange instead of implementing firstIndex
We have `firstRange` in the stdlib now, so we don’t need to implement `firstIndex` ourselves.
2024-08-08 09:19:29 -07:00
Alex Hoppen
50a28bb86a Change FIXME and TODO comments to always have an associated issue
Do one of the following for every `FIXME` or `TODO` comment
- Add an issue that tracks the task
- Remove the comment if we are not planning to address it
2024-08-07 10:00:04 -07:00
Alex Hoppen
8c34a76f59 Rename LSPLogging to SKLogging 2024-07-25 09:11:13 -07:00
Alex Hoppen
2877675bd5 Adopt package access level
Change a l public declarations to the `package` access level, accept for:
- The `LanguageServerProtocol` module
- The `BuildServerProtocol` module
- `InProcessClient.InProcessSourceKitLSPClient`
- `LanguageServerProtocolJSONRPC` (I would like to create a more ergonomic API for this like `InProcessSourceKitLSPClient` in the future, but for now, we’ll leave it public)

Unfortunately, our pattern of marking functions as `@_spi(Testing) public` no longer works with the `package` access level because declarations at the `package` access level cannot be marked as SPI. I have decided to just mark these functions as `package`. Alternatives would be:
- Add an underscore to these functions, like we did for functions exposed for testing before the introduction of `SPI`
- Use `@testable` import in the test targets and mark the methods as `internal`

Resolves #1315
rdar://128295618
2024-07-19 09:54:30 -07:00
Finagolfin
7c20015331 Import new Android overlay 2024-07-04 02:20:23 +05:30
Alex Hoppen
9618df80a0 Add documentation about each module's purpose and move some files between modules
The purpose of the different modules wasn’t clearly defined, which lead to inconsistent responsibilities between the different modules. Define each module’s purpose and move a few files between modules to satisfy these definitions.

There are a few more larger changes that will need to be made for a fully consistent module structure. These are FIXMEs in the new Modules.md document and I’ll address them in follow-up PRs.
2024-06-25 07:47:45 -07:00
Alex Hoppen
33d803f1d1 Change methods that were only public for testing purposes to be @_spi(Testing)
Fixes #876
Fixes #877
rdar://116705648
rdar://116705669
2024-06-11 19:03:26 -07:00
Alex Hoppen
7f90508e51 Add a document to describe which log level to use
Also change a few log levels and make all log messages consistently start with an uppercase letter.
2024-06-11 12:01:50 -07:00
Alex Hoppen
7a65050c33 Don’t fatalError if encoding a message to the client could not be encoded 2024-04-04 11:05:53 -07:00
Alex Hoppen
be42621f4c Don’t crash sourcekit-lsp if a known message is missing a field
Previously, we `fatalError`ing when `JSONDecoder` failed to decode a message from the client. Instead of crashing, try recovering from such invalid messages as best as possible. If we know that the state might  have gotten out of sync with the client, show a notification message to the user, asking them to file an issue.

rdar://112991102
2024-04-02 07:50:03 +02:00
Alex Hoppen
6edc462d09 Remove --sync option
With the `test-sourcekit-lsp.py` integration test rewritten to not use `--sync`, there are no more users of this option. Remove it since we don’t really test it anyway.
2024-03-22 08:45:57 +01:00
Alex Hoppen
d1b527e14c Make the LanguageServerProtocolJSONRPC module build with strict concurrency enabled 2024-03-20 08:37:39 +01:00
Alex Hoppen
259da4554e Improve queue handling in JSONRPCConnection
This started off by guarding `state` against concurrent access and then escalated slightly.

The main changes are:
- `state` must only be accessed on `queue` now, preventing race conditions of message handling while the connection is being closed.
- A few functions were renamed, merged, and documented to simplify the code
- A few dead members were removed
2024-03-20 08:30:16 +01:00
Alex Hoppen
3007d9f392 Naming improvements, added comments and typo fixes in connection related code
This should make the code easier to understand. No functionality change.
2024-03-20 08:30:16 +01:00
Alex Hoppen
7c46df3abe Remove clientID from request handling
The client ID was needed when a `MessageHandler` could handle messages from multiple connections. We don’t support this anymore (because it wasn’t needed) and so the client ID doesn’t need to get passed through as well.
2024-03-20 08:28:26 +01:00
Alex Hoppen
757a029664 Log messages from the build server and clangd
Log messages sent to clangd and the build server in a similar way that we log requests to sourcekitd.

Fixes #886
rdar://116705677
2023-12-12 14:05:25 -08:00
Alex Hoppen
f960d7ed9b Change logging to use OSLog
OSLog is the suggesting logging solution on Apple platforms and we should be using it there, taking advantage of the different log levels and privacy masking.

Switch sourcekit-lsp to use OSLog on Apple platforms and implement a logger that is API-compatible with OSLog for all uses in sourcekit-lsp and which can be used on non-Darwin platforms.

The goal of this commit is to introduce the new logging API. There are still improvements about what we log and we can display more privacy-insensitive information after masking. Those changes will be in follow-up commits.
2023-10-13 13:46:32 -07:00
Alex Hoppen
d0fc00ce98 Format using swift-format
Add `.swift-format` to the repo and format the repo with `swift-format`.

This commit does not add any automation to enforce formatting of sourcekit-lsp in CI. The goal of this commit is to get the majority of source changes out of the way so that the diff of actually enforcing formatting will have fewer changes or conflicts.
2023-10-10 13:44:47 -07:00
Alex Hoppen
4495256b35 Remove the queue parameter from Connection.send
We don’t actually care about the queue that we receive the reply on anymore since we migrated everything™ to actors/async/await.
2023-10-06 18:07:20 -07:00
Andrey Klebanov
e441299449 Addressed code review comments:
- change closeHandler's type to optional

Issue: #852 closeHandler callback can be nil in an initializer
2023-10-05 11:31:13 -04:00
Andrey Klebanov
785b00c438 Don't call closeHandler if it is nil
Issue: #852 closeHandler callback can be nil in an initializer
2023-10-04 20:14:09 -04:00
Alex Hoppen
1f02b95e55 Shift responsibility for in-order message handling from Connection to SourceKitServer
This generally seems like the cleaner design because `SourceKitServer` is actually able to semantically inspect the message and decide whether it can be handled concurrently with other requests.
2023-10-03 07:56:49 -07:00
Alex Hoppen
edfda7d743 Add support for concurrent queues and dispatch barriers to AsyncQueue 2023-10-03 07:56:49 -07:00
Alex Hoppen
34c6b81295 Move semaphore signalling 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-10-02 09:45:27 -07:00
Alex Hoppen
09dc0bc82f 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-10-02 09:43:42 -07:00
Alex Hoppen
ce58b3b2a5 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-10-02 09:43:39 -07:00
Alex Hoppen
9ec614942a 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-10-02 09:43:36 -07:00
Alex Hoppen
b22af35eb1 Revert asyncificaiton changes
The asyncification changes caused some non-deterministic test failures. I believe that some of these are due to race conditions that are the result of the partial transition to actors.

Instead of merging the asyncification piece by piece, I will collect the changes asyncification changes in a branch and then qualify that branch througougly (running CI multiple times) before merging it into `main`.
2023-09-30 10:09:59 -07:00
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