Skip to content

delayOpenNotifications=true results in the wrong document version and content being sent in didOpen notification #1695

@DanTup

Description

@DanTup

I enabled delayOpenNotifications in the pre-release version of my extension but a bug came up that it was corrupting the servers overlays for open files in some cases.

I was able to reproduce this, and it seems to happen when code actions create new files with contents. The delayed didOpen notification gets sent with the "updated" content/version of the file instead of what it would've been had the notification not been delayed.

For example given a code action that has:

"edit": {
    "documentChanges": [
        {
            "kind": "create",
            "uri": "file:///D:/foo/foo.dart"
        },
        {
            "edits": [
                {
                    "newText": "part of 'sort_declarations.dart';\r\n\r\n",
                    "range": { "end": { "character": 0, "line": 0 }, "start": { "character": 0, "line": 0 } }
                }
            ],
            "textDocument": { "uri": "file:///D:/foo/foo.dart", "version": null }
        }
    ]
},

Without delayed notifications, this results in the following LSP traffic, which opens the file (empty) and then applies the edit:

==> {"method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///D%3A/foo/foo.dart","languageId":"dart","version":1,"text":""}}}
==> {"method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///D%3A/foo/foo.dart","version":2},"contentChanges":[{"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"rangeLength":0,"text":"part of 'sort_declarations.dart';\r\n\r\n"}]}}

However, with delayed notifications enabled, we get a didOpen that has the modified content in it, and then the didChange notification re-inserts the same text, resulting in duplication of content in the servers version of the file:

==> {"method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///D%3A/foo/foo.dart","languageId":"dart","version":2,"text":"part of 'sort_declarations.dart';\r\n\r\n"}}}
==> {"method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///D%3A/foo/foo.dart","version":2},"contentChanges":[{"range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}},"rangeLength":0,"text":"part of 'sort_declarations.dart';\r\n\r\n"}]}}
Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions