Skip to content

Commit 01640ee

Browse files
authored
Merge pull request #1731 from ahoppen/bsp-implementation-documentation
Add a document that describes the basic steps needed to implement a BSP server
2 parents ee29e31 + c2d1c15 commit 01640ee

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
@@ -18,7 +18,8 @@ export interface SourceKitInitializeBuildResponseData {
1818
* for `swiftc` or `clang` invocations **/
1919
indexStorePath?: string;
2020

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

2425
/** Whether the build server supports the `buildTarget/prepare` request */
@@ -42,9 +43,9 @@ export interface SourceKitInitializeBuildResponseData {
4243

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

45-
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.
46+
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.
4647

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

4950
- method: `buildTarget/prepare`
5051
- 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
@@ -21,10 +21,14 @@ public typealias OriginId = String
2121
/// The prepare build target request is sent from the client to the server to prepare the given list of build targets
2222
/// for editor functionality.
2323
///
24-
/// To do so, the build server should build Swift modules for all dependencies of this module so that all `import`
25-
/// statements in this module can be resolved.
24+
/// To do so, the build server should perform any work that is necessary to typecheck the files in the given target.
25+
/// This includes, but is not limited to: Building Swift modules for all dependencies and running code generation scripts.
26+
/// Compared to a full build, the build server may skip actions that are not necessary for type checking, such as object
27+
/// file generation but the exact steps necessary are dependent on the build system. SwiftPM implements this step using
28+
/// the `swift build --experimental-prepare-for-indexing` command.
2629
///
27-
/// The server communicates during the initialize handshake whether this method is supported or not.
30+
/// The server communicates during the initialize handshake whether this method is supported or not by setting
31+
/// `prepareProvider: true` in `SourceKitInitializeBuildResponseData`.
2832
public struct BuildTargetPrepareRequest: RequestType, Hashable {
2933
public static let method: String = "buildTarget/prepare"
3034
public typealias Response = VoidResponse

0 commit comments

Comments
 (0)