Skip to content

Commit c2d1c15

Browse files
committed
Add a document that describes the basic steps needed to implement a BSP server
1 parent 9b4a9b0 commit c2d1c15

File tree

4 files changed

+59
-6
lines changed

4 files changed

+59
-6
lines changed

Contributor Documentation/BSP Extensions.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export interface SourceKitInitializeBuildResponseData {
1212
* for `swiftc` or `clang` invocations **/
1313
indexStorePath?: string;
1414

15-
/** The path at which SourceKit-LSP can store its index database, aggregating data from `indexStorePath` */
15+
/** The path at which SourceKit-LSP can store its index database, aggregating data from `indexStorePath`.
16+
* This should point to a directory that can be exclusively managed by SourceKit-LSP. Its exact location can be arbitrary. */
1617
indexDatabasePath?: string;
1718

1819
/** Whether the build server supports the `buildTarget/prepare` request */
@@ -31,9 +32,9 @@ export interface SourceKitInitializeBuildResponseData {
3132

3233
The prepare build target request is sent from the client to the server to prepare the given list of build targets for editor functionality.
3334

34-
To do so, the build server should build Swift modules for all dependencies of this module so that all `import` statements in this module can be resolved.
35+
To do so, the build server should perform any work that is necessary to typecheck the files in the given target. This includes, but is not limited to: Building Swift modules for all dependencies and running code generation scripts. Compared to a full build, the build server may skip actions that are not necessary for type checking, such as object file generation but the exact steps necessary are dependent on the build system. SwiftPM implements this step using the `swift build --experimental-prepare-for-indexing` command.
3536

36-
The server communicates during the initialize handshake whether this method is supported or not by setting `supportsPreparation` in `SourceKitInitializeBuildResponseData`.
37+
The server communicates during the initialize handshake whether this method is supported or not by setting `prepareProvider: true` in `SourceKitInitializeBuildResponseData`.
3738

3839
- method: `buildTarget/prepare`
3940
- params: `PrepareParams`
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Implementing a BSP server
2+
3+
SourceKit-LSP can connect to any build system to provide semantic functionality through the [Build Server Protocol (BSP)](https://build-server-protocol.github.io). This is a short guide of the requests and notifications that a BSP server for SourceKit-LSP should implement. For more detailed information, refer to the [BSP spec](https://build-server-protocol.github.io/docs/specification) and the [SourceKit-LSP BSP Extensions](BSP%20Extensions.md). This document just references BSP methods and properties and those specification documents contain their documentation.
4+
5+
## Required lifecycle methods
6+
7+
In order to be launched and shut down successfully, the BSP server must implement the following methods
8+
9+
- `build/initialize`
10+
- `build/initialized`
11+
- `build/shutdown`
12+
- `build/exit`
13+
14+
The `build/initialize` response must have `dataKind: "sourceKit"` and `data.sourceKitOptionsProvider: true`. In order to provide global code navigation features such as call hierarchy and global rename, the build server must set `data.indexDatabasePath` and `data.indexStorePath`.
15+
16+
## Retrieving build settings
17+
18+
In order to provide semantic functionality for source files, the BSP server must provide the following methods:
19+
20+
- `workspace/buildTargets`
21+
- `buildTarget/sources`
22+
- `textDocument/sourceKitOptions`
23+
- `buildTarget/didChange`
24+
- `workspace/waitForBuildSystemUpdates`
25+
26+
If the build system does not have a notion of targets, eg. because it provides build settings from a file akin to a JSON compilation database, it may use a single dummy target for all source files or a separate target for each source file, either choice will work.
27+
28+
If the build system loads the entire build graph during initialization, it may immediately return from `workspace/waitForBuildSystemUpdates`.
29+
30+
31+
## Supporting background indexing
32+
33+
To support background indexing, the build system must set `data.prepareProvider: true` in the `build/initialize` response and implement the `buildTarget/prepare` method.
34+
35+
## Optional methods
36+
37+
The following methods are not necessary to implement for SourceKit-LSP to work but might help with the implementation of the build server.
38+
39+
- `build/logMessage`
40+
- `window/workDoneProgress/create`
41+
- `workspace/didChangeWatchedFiles`
42+
- `$/progress`
43+
44+
## Build server discovery
45+
46+
To make your build server discoverable, create a [BSP connection specification](https://build-server-protocol.github.io/docs/overview/server-discovery) file named `buildServer.json` in the root of your project.

Contributor Documentation/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
The following documentation documents are primarily intended for developers of SourceKit-LSP.
44

55
- [Background Indexing](Background%20Indexing.md)
6+
- [BSP Extension](BSP%20Extensions.md)
67
- [Files To Reindex](Files%20To%20Reindex.md)
8+
- [Implementing a BSP server](Implementing%20a%20BSP%20server.md)
79
- [LSP Extensions](LSP%20Extensions.md)
810
- [Logging](Logging.md)
911
- [Modules](Modules.md)

Sources/BuildServerProtocol/Messages/BuildTargetPrepareRequest.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ public typealias OriginId = String
1717
/// The prepare build target request is sent from the client to the server to prepare the given list of build targets
1818
/// for editor functionality.
1919
///
20-
/// To do so, the build server should build Swift modules for all dependencies of this module so that all `import`
21-
/// statements in this module can be resolved.
20+
/// To do so, the build server should perform any work that is necessary to typecheck the files in the given target.
21+
/// This includes, but is not limited to: Building Swift modules for all dependencies and running code generation scripts.
22+
/// Compared to a full build, the build server may skip actions that are not necessary for type checking, such as object
23+
/// file generation but the exact steps necessary are dependent on the build system. SwiftPM implements this step using
24+
/// the `swift build --experimental-prepare-for-indexing` command.
2225
///
23-
/// The server communicates during the initialize handshake whether this method is supported or not.
26+
/// The server communicates during the initialize handshake whether this method is supported or not by setting
27+
/// `prepareProvider: true` in `SourceKitInitializeBuildResponseData`.
2428
public struct BuildTargetPrepareRequest: RequestType, Hashable {
2529
public static let method: String = "buildTarget/prepare"
2630
public typealias Response = VoidResponse

0 commit comments

Comments
 (0)