And if any of these checks fail, we just return on defy to indicate that the refactor cannot be applied here. The response is then sent back to the editor, which performs an analogous translation to add those refactorings to the lightbulb list. The editor now unfolded the code action list and showed the user how they could improve their code. They picked the best action ever, of inline variable, and we sent another request to tserver. Code actions are an example of a tserver command that happens in two stages. In getApplicableRefactors we just notified the editors which refactors could be applied, but we didn't tell it how. Refactorings might seem special here. But there are other operations with two steps that you've used a lot already. Completions are another example. Let's go back to the handler for this refactor. When asked to apply the action, it will again ask the compiler for the node that's being inline, the references to it, as well as the expression we'll replace the variable with. It then updates all the references to use the value instead of the variable identifier. And finally, it gets rid of the now on use variable. After the editor reads and translates the response, the refactor is finally applied. Now that you're TS Server experts, impress editor and TypeScript maintainers the next time you encounter a bug and create a GitHub issue. Say that when applying the code action, the modified line is off by one. Without further context, this is a language server bug. Also, if it's a server bug you would be able to reproduce the issue in another editor. As another scenario, say that when clicking on the light bulb, the displayed list has duplicate items. This is an editor bug. If you really want to look like a professional, you can even take a look at the TS server logs, or by setting TypeScript trace level to verbose in VS Code, to see what exactly the server is receiving and returning. That will help pinpoint where things go downhill.
And if any of these checks fail, we just return on defy to indicate that the refactor cannot be applied here. The response is then sent back to the editor, which performs an analogous translation to add those refactorings to the lightbulb list.
And fantastic! The editor now unfolded the code action list and showed the user how they could improve their code. They picked the best action ever, of inline variable, and we sent another request to tserver.
At this point you might be wondering, why do we need to talk to tserver again? This is because code actions are an example of a tserver command that happens in two stages. In getApplicableRefactors we just notified the editors which refactors could be applied, but we didn't tell it how. This is because we don't want to compute all the necessary file modifications for refactorings if you won't even click on them. Only when the refactoring is actually selected, the editor will ask tsserver to apply the chosen item.
Refactorings might seem special here. But there are other operations with two steps that you've used a lot already. Completions are another example, you might have a completion item with an exported object from another file. If selected, not only the completed line will be modified, TypeScript will also update your imports to make sure the new reference is valid. You know the drill, the editor registers a selection, which later the TypeScript client will map back to the refactor it received in the previous request. From that, it constructs the commands arguments following the TypeScript protocol. And when it receives the result, it will return the workspace edits, which include file modifications, additions and removals that the refactor implies.
Let's go back to the handler for this refactor. When asked to apply the action, it will again ask the compiler for the node that's being inline, the references to it, as well as the expression we'll replace the variable with. It then updates all the references to use the value instead of the variable identifier. And finally, it gets rid of the now on use variable. And ta-da! After the editor reads and translates the response, the refactor is finally applied.
Now that you're TS Server experts, impress editor and TypeScript maintainers the next time you encounter a bug and create a GitHub issue. Say that when applying the code action, the modified line is off by one. Without further context, I would dare to say that this is a language server bug, since at the end of the day the editor is blindly applying the change that the server told it to do. Also, if it's a server bug you would be able to reproduce the issue in another editor, so you can also try that. As another scenario, say that when clicking on the light bulb, the displayed list has duplicate items. This is a bit harder to say, but from my experience, I would guess that this is an editor bug, since it is the one responsible for querying the code action providers, combining the results and displaying them in the UI. As a funny story, one of the first bugs that I fixed at Microsoft was duplicate completion entries in Visual Studio. It was both a fascinating, but slightly traumatizing experience. If you really want to look like a professional, you can even take a look at the TS server logs, or by setting TypeScript trace level to verbose in VS Code, to see what exactly the server is receiving and returning. That will help pinpoint where things go downhill.
Comments