-
Notifications
You must be signed in to change notification settings - Fork 378
Description
VS Code version: Code 1.74.0
OS Version: All
vscode-languageclient: 8.0.1
In the C/C++ extension, we maintain copies of open file buffers in our native LSP process, for various reasons. We keep those buffers up to date by processing didOpen, didChange, etc.. Also, in TypeScript, we use a Middleware instance to filter these messages (and ensure they are processed serially with regards to other messages we have queued).
The issue is most obvious with the didChange message. The Middleware would appear to support async handlers. The return type of the didChange handler is a Promise<void>. In our Middleware, we may await another function before calling sendMessage. We pass sendMessage the original parameters that were passed to us. We are seeing that when our didChange handler cannot complete immediately, the call to sendMessage will effectively re-evaluate the originally provided TextDocumentChangeEvent, such that it now contains a more recent document version than was associated with the specified contentChanges.
didChange: async (textDocumentChangeEvent, sendMessage) => {
await somethingThatCantCompleteImmediately(); // If this doesn't complete immediately, and an edit races with us,
await sendMessage(textDocumentChangeEvent); // this will send an incorrect document version.
},
This mismatch between the change/edit data and the document version results in corruption of our internal buffer, as we are using the version value to ensure we do not apply stale edits, for example.
If the Middleware allows async handlers, VS Code should ensure that the parameters passed to them will not change out from under them before they complete.
Deep-copying the parameters might be a work-around, but some are complex, and we don't necessarily know what sendMessage does with the parameters we pass to it. Another work-around might be for us to remove our calls to sendMessage and create our own custom messages, passing them only the parameters we care about, pinned to their original values.
I can create a simplified repo if needed. I figured I would get this issue opened first. I could potentially provide a fork of cpptools, with some minor modifications to restore the above pattern, if the above info does not make the issue sufficiently obvious.