<p>I’ve recently written a compiler and I wouldn’t mind turning it into a language server.  I’m also sitting on a couple of interpreters that I would like to turn into language servers.  And I’m planning to start a new compiler that could potentially be designed as a language server from the get-go.</p>
<p>But there’s a problem: I can’t find guidance.  All I’ve found is, “Study the Language Server Protocol.”  But that’s not enough.  Here are some unanswered questions:</p>
<ul>
<li>What LSP features should I implement first? Which should I delay until later or not at all?</li>
<li>What parts of my compiler or interpreter should I expect to reuse as is? What parts should I plan on reusing with minor changes?  What parts (besides code generation) should I plan <em>not</em> to reuse?</li>
</ul>

<language-server-protocol>
What are good tactics for implementing a language server?
<p>Let me assume your compiler has a type checking process which outputs compilable ASTs. Then, I expect you to reuse everything in and before this phase. A type checking process will require names to be resolved, and this information will be useful.</p>
<p>What to implement first?</p>
<ol start="0">
<li>Report error messages in the source code. This should be the easiest.</li>
<li>Go to definition. The easiest yet important feature to implement, which also builds the foundation for code completion. This will make use of the name resolving information.</li>
<li>Find usages. This is a simple extension to 'go to definition'.</li>
<li>Rename. Also a simple extension.</li>
<li>Various 'source code queries' such as lookup function signature, show documentation of a function, etc.</li>
</ol>
<p>In order to implement some useful features, you may need the following:</p>
<ol>
<li>Parse incomplete code. Also prepares for code completion.</li>
<li>Syntax tree needs to contain source information and should be carried through in the type checking process.</li>
<li>Build string from a syntax tree. Suppose you want to implement refactoring, then you'll need to generate code from transformed ASTs. It would be better if you can build a patch of code from a diff of two syntax trees.</li>
</ol>
<p>After these preparations, you may work on the following:</p>
<ol>
<li>Code completion. Hard, but most useful.</li>
<li>Refactoring. Use your imagination to do as much as you can!</li>
<li>Debugging. This is a separate topic.</li>
<li>Formatting. This is another separate topic.</li>
<li>And much more!</li>
</ol>

CC BY-SA 4.0
2023-05-18T23:48:58.613Z
2023-05-18T23:48:58.613Z
ice1000
# What are good tactics for implementing a language server?
Posted by: username_0 on 2023-05-18
I’ve recently written a compiler and I wouldn’t mind turning it into a language server. I’m also sitting on a couple of interpreters that I would like to turn into language servers. And I’m planning to start a new compiler that could potentially be designed as a language server from the get-go.

But there’s a problem: I can’t find guidance. All I’ve found is, “Study the Language Server Protocol.” But that’s not enough. Here are some unanswered questions:

* What LSP features should I implement first? Which should I delay until later or not at all?
* What parts of my compiler or interpreter should I expect to reuse as is? What parts should I plan on reusing with minor changes? What parts (besides code generation) should I plan *not* to reuse?
**Tags:** language-server-protocol
---
## 1 answers
### Answer by username_1 on 2023-05-18. Score: 4
Let me assume your compiler has a type checking process which outputs compilable ASTs. Then, I expect you to reuse everything in and before this phase. A type checking process will require names to be resolved, and this information will be useful.

What to implement first?

0. Report error messages in the source code. This should be the easiest.
1. Go to definition. The easiest yet important feature to implement, which also builds the foundation for code completion. This will make use of the name resolving information.
2. Find usages. This is a simple extension to 'go to definition'.
3. Rename. Also a simple extension.
4. Various 'source code queries' such as lookup function signature, show documentation of a function, etc.

In order to implement some useful features, you may need the following:

1. Parse incomplete code. Also prepares for code completion.
2. Syntax tree needs to contain source information and should be carried through in the type checking process.
3. Build string from a syntax tree. Suppose you want to implement refactoring, then you'll need to generate code from transformed ASTs. It would be better if you can build a patch of code from a diff of two syntax trees.

After these preparations, you may work on the following:

1. Code completion. Hard, but most useful.
2. Refactoring. Use your imagination to do as much as you can!
3. Debugging. This is a separate topic.
4. Formatting. This is another separate topic.
5. And much more!
---
