[GSoC 2025] Improvement of code completion documentation in SourceKit-LSP

Hey! I wanted to express my interest in joining GSoC with Swift this year. I'm particularly interested in the topic of improving the display of documentation during code completion in SourceKit-LSP with @ahoppen

I have some experience working with Gradle LSP and BSP implementations, so I am familiar with how LSP works in general. However, I haven't delved into the finer details of how a language backend provides a meaningful developer experience. That’s something I’m looking forward to learning here.

I'm fairly new to Swift, but I have experience with languages like Rust and C++, so in that regard, this environment feels familiar and like a place where I can thrive. I have reviewed the project description and set up a local development environment for SourceKit-LSP and the Swift language to begin testing. I'm currently playing with a development instance of sourcekit-lsp to see how it works currently.

I have a few questions regarding the project proposal that I’d like to clarify to get me going:

  • How exactly does SourceKit-LSP and the Swift backend communicate with each other to get the existing code intelligence functionality?
  • How does CodeCompletion.cpp interact with other elements of Swift lang to provide code completion features? Navigating and understanding such a large codebase is quite intimidating for me, so having a clear starting point along with an explanation of how the existing implementation works would be extremely helpful.
  • What changes would be required in Swift's codebase to implement the LSP signature help request in order to provide code completion results? Would all of these changes be limited to CodeCompletion.cpp, or would modifications be needed outside of CodeCompletion.cpp as well to allow these changes to work? In other words, does Swift already have a built-in suggestions API that just needs to be integrated with LSP, or does this functionality need to be implemented from scratch?

Looking forward to your input! Thanks, akshit.

2 Likes

Hi @akshitsinha,

Great to hear that you are interested in contributing to SourceKit-LSP!

sourcekit-lsp/Contributor Documentation/Overview.md at main · swiftlang/sourcekit-lsp · GitHub has a short overview on how SourceKit-LSP and sourcekitd communicate with each other. Essentially, SourceKit-LSP will send requests to sourcekitd through the SourceKitD type in its codebase and sourcekitd will start handling them in its Requests.cpp file

The gist is that code completion starts Swift’s type checker with a special CodeCompletionExpr inserted at the location at which code completion should be performed. The constraint system will then produce possible solutions for the expression (multiple in case there is ambiguity, eg. in the case of overloads) and we inspect those solutions to (among others) infer the type that we are completing on and then use the compiler’s name lookup logic to find members on that type to suggest. There are a few types conforming to TypeCheckCompletionCallback in lib/IDE that provide most of the code completion functionality. For example ArgumentCompletion provides the completion when inside a call. sawSolutionImpl infers the information we need during completion and collectResults produces the actual results based on that information.

You can see some of this in action when building the compiler locally and running swift-ide-test -code-completion -code-completion-token COMPLETE -source-filename /path/to/file.swift -sdk $(xcrun --show-sdk-path --sdk macosx) -debug-constraints on a file that contains #^COMPLETE^# at the location where you want to perform completion. Reading and understanding that output is non-trivial though.

This would require new functionality to be implemented in ArgumentCompletion.cpp and to be exposed through a new sourcekitd request. How exactly that should work would be part of the GSoC project.

– Alex

3 Likes

Hey Alex, thanks for the response.

I'm using this sample code as a way to test what the current implementation can do.


And when I type in calculateArea( I get

as the completion results, I can see the documentation and return type, but not the information about about the function parameters or the return type.
As per the project description,

Every code completion item can have documentation associated with it and while completing a function signature, the editor can display the available overloads, parameter names and their documentation through signature help. Currently, SourceKit-LSP only displays the first line of an item’s documentation in the code completion results and does not provide any signature help.

This project would implement functionality to return the entire documentation for all code completion items and also implement the LSP signature help request.

textDocument/hover already has this functionality of being able to read the documentation with respect to the overload being in use as seen here

I assume that by looking over how textDocument/hover works, and similarly implementing the same functionality with textDocument/signatureHelp, we can achieve the desired outcome for this proposal. Is this the only deliverable? Is this what constitutes signatureHelp? I feel like I might be missing something here, as this doesn’t seem to make sense as an intermediate project in that case.

Thanks, akshit.

I don’t expect major challenges with the display of the full documentation for code completion items either. The challenging part for signature help will be to figure out which parameter you are currently entering. We currently have logic like this only for argument completions, eg. with the following, the cursor being at |.

func test(a: Int, b: Int = 1, c: Int = 2, d: Int) {}
test(a: 1, |

This currently suggests both b, c and d as argument labels. We need similar behavior for signature help (though we might be able to re-use significant parts here). And just getting everything to build and passing the information through different layers will, in my experience, make this an intermediate project :wink:

2 Likes

Hey thanks for the reply!

I'll be then looking more into how hoverRequest request works under the hood and try to get a prototype working with signatureHelp with at least some of the hoverRequest features working, it should also be a good way to learn how the information goes through the layers, which I think should be a good point to start. I get some of the layers, but I feel like there are a lot which could take some time to understand. So in the process I tried to build a local copy of sourcekit-lsp and ran it on my own vscode for debugging. The screenshot I attached earlier uses the local build of sourcekit-lsp which I was building using swift build. But recently, after the latest snapshot I run into this error when using swift build


When building alongside swift with --sourcekit-lsp and --install-sourcekit-lsp flags, it still works, but the problem is that it builds the release version of sourcekit-lsp and I cannot see an option to specify to create a debug variant of sourcekit-lsp specifically, and I cannot use lldb to debug with it. I tried changing SOURCEKIT_TOOLCHAIN_PATH, but had no luck there. Could you provide a lead on how to debug this, and sourcekit-lsp itself more efficiently?

1 Like

I think you just need to run swift package update to update SourceKit-LSP’s dependencies. After that compiler should be defined on SwiftBuildTarget.

2 Likes