I was originally thinking to design the compilier upfront as a compiler and LSP server as well, but the answers there dissuaded me from making them share all code. But, I would still like them to share some code to make my life easier. So, what are some parts of the code that they can share?
-
1$\begingroup$ I'm still not convinced it is a good idea to separate compiler and LSP. They still share the parser and a good part of compilation pipeline (without optimisations and backend). You want to see in LSP all the same compiler errors you see when compiling in normal mode, right? $\endgroup$– SK-logicCommented Jul 5, 2023 at 11:17
-
$\begingroup$ Yes but it seems much more complicated @SK-logic $\endgroup$– StarshipCommented Jul 5, 2023 at 11:18
-
$\begingroup$ Why is it more complicated? You need a parser anyway - just use parsing techniques that are friendly to partial re-parsing. You need a typing pass, you need to resolve the identifiers, etc - in both LSP and compiler. Just make it possible to stop compilation after those passes, and allow incremental edits. $\endgroup$– SK-logicCommented Jul 5, 2023 at 12:57
-
$\begingroup$ Read the linked question $\endgroup$– StarshipCommented Jul 5, 2023 at 14:40
-
$\begingroup$ I did (and I left an answer there), I still don't agree with any of the supposed complexities of such an architecture. Gavin Howard answer is mostly relevant to the case when you already have a compiler and want to retro-fit it as an LSP server. I imagine it can be problematic if the original compiler design is not flexible enough. But if you start from scratch, none of those points really matter. $\endgroup$– SK-logicCommented Jul 5, 2023 at 15:27
1 Answer
The information required by LSP is more detailed, and many of them can be reused by the compiler.
textDocument/diagnostic
Various syntax errors and compile-time errors in LSP can be reported using this endpoint.
In the compiler, when you execute through the command line, you also need to display this information again.
textDocument/inlayHint
When you do static type checking, record the type of each variable and display it using this endpoint.
textDocument/signatureHelp
Before using this capability, it is necessary to implement the ability to query token objects in the language according to offset or (line, column)
,
This is also part of type checking, you need to know the actual type of each call.
textDocument/references
and textDocument/typeDefinition
When you check whether the call is legal, cache the result of the check in the call symbol, and then reverse the query in the same way as before.
This can implement interfaces such as definition jumps, as well as record where functions or interfaces are called.
workspace/semanticTokens/refresh
After you verify the references of all symbols, you should know the attributes of each symbol, and you can update the semantic highlighting through this endpoint.