Re: [clang-tools-extra] r328500 - [clangd] Support incremental document syncing
On 2018-03-27 01:47 PM, Reid Kleckner wrote: > One of these new tests does not pass on Windows due to assumptions about > absolute path structure. The FileCheck output seems self-explanatory: > > $ "FileCheck" "-strict-whitespace" > "C:\b\slave\clang-x86-windows-msvc2015\clang-x86-windows-msvc2015\llvm\tools\clang\tools\extra\test\clangd\textdocument-didchange-fail.test" > # command stderr: > C:\b\slave\clang-x86-windows-msvc2015\clang-x86-windows-msvc2015\llvm\tools\clang\tools\extra\test\clangd\textdocument-didchange-fail.test:22:20: > error: expected string not found in input > # CHECK-NEXT: "uri": "file:///clangd-test/main.cpp" > ^ > :68:7: note: scanning from here > "uri": "file:///C%3a/clangd-test/main.cpp" > > I committed a speculative fix for this in r328645, hopefully it does the job. Makes sense. Thanks for catching and fixing it! I received some failure notifications, but at first sight they seemed unrelated (maybe some of them were). I'll look more closely next time. Simon ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [clang-tools-extra] r328500 - [clangd] Support incremental document syncing
One of these new tests does not pass on Windows due to assumptions about absolute path structure. The FileCheck output seems self-explanatory: $ "FileCheck" "-strict-whitespace" "C:\b\slave\clang-x86-windows-msvc2015\clang-x86-windows-msvc2015\llvm\tools\clang\tools\extra\test\clangd\textdocument-didchange-fail.test" # command stderr: C:\b\slave\clang-x86-windows-msvc2015\clang-x86-windows-msvc2015\llvm\tools\clang\tools\extra\test\clangd\textdocument-didchange-fail.test:22:20: error: expected string not found in input # CHECK-NEXT: "uri": "file:///clangd-test/main.cpp" ^ :68:7: note: scanning from here "uri": "file:///C%3a/clangd-test/main.cpp" I committed a speculative fix for this in r328645, hopefully it does the job. On Mon, Mar 26, 2018 at 7:32 PM Simon Marchi via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: simark > Date: Mon Mar 26 07:41:40 2018 > New Revision: 328500 > > URL: http://llvm.org/viewvc/llvm-project?rev=328500=rev > Log: > [clangd] Support incremental document syncing > > Summary: > This patch adds support for incremental document syncing, as described > in the LSP spec. The protocol specifies ranges in terms of Position (a > line and a character), and our drafts are stored as plain strings. So I > see two things that may not be super efficient for very large files: > > - Converting a Position to an offset (the positionToOffset function) > requires searching for end of lines until we reach the desired line. > - When we update a range, we construct a new string, which implies > copying the whole document. > > However, for the typical size of a C++ document and the frequency of > update (at which a user types), it may not be an issue. This patch aims > at getting the basic feature in, and we can always improve it later if > we find it's too slow. > > Signed-off-by: Simon Marchi> > Reviewers: malaperle, ilya-biryukov > > Reviewed By: ilya-biryukov > > Subscribers: MaskRay, klimek, mgorny, ilya-biryukov, jkorous-apple, > ioeric, cfe-commits > > Differential Revision: https://reviews.llvm.org/D44272 > > Added: > clang-tools-extra/trunk/test/clangd/textdocument-didchange-fail.test > clang-tools-extra/trunk/unittests/clangd/DraftStoreTests.cpp > Modified: > clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp > clang-tools-extra/trunk/clangd/DraftStore.cpp > clang-tools-extra/trunk/clangd/DraftStore.h > clang-tools-extra/trunk/clangd/Protocol.cpp > clang-tools-extra/trunk/clangd/Protocol.h > clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test > clang-tools-extra/trunk/test/clangd/initialize-params.test > clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt > > Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp > URL: > http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=328500=328499=328500=diff > > == > --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) > +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Mon Mar 26 07:41:40 > 2018 > @@ -100,7 +100,7 @@ void ClangdLSPServer::onInitialize(Initi >reply(json::obj{ >{{"capabilities", > json::obj{ > -{"textDocumentSync", 1}, > +{"textDocumentSync", (int)TextDocumentSyncKind::Incremental}, > {"documentFormattingProvider", true}, > {"documentRangeFormattingProvider", true}, > {"documentOnTypeFormattingProvider", > @@ -147,25 +147,30 @@ void ClangdLSPServer::onDocumentDidOpen( >PathRef File = Params.textDocument.uri.file(); >std::string = Params.textDocument.text; > > - DraftMgr.updateDraft(File, Contents); > + DraftMgr.addDraft(File, Contents); >Server.addDocument(File, Contents, WantDiagnostics::Yes); > } > > void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams > ) { > - if (Params.contentChanges.size() != 1) > -return replyError(ErrorCode::InvalidParams, > - "can only apply one change at a time"); >auto WantDiags = WantDiagnostics::Auto; >if (Params.wantDiagnostics.hasValue()) > WantDiags = Params.wantDiagnostics.getValue() ? WantDiagnostics::Yes >: WantDiagnostics::No; > >PathRef File = Params.textDocument.uri.file(); > - std::string = Params.contentChanges[0].text; > + llvm::Expected Contents = > + DraftMgr.updateDraft(File, Params.contentChanges); > + if (!Contents) { > +// If this fails, we are most likely going to be not in sync anymore > with > +// the client. It is better to remove the draft and let further > operations > +// fail rather than giving wrong results. > +DraftMgr.removeDraft(File); > +Server.removeDocument(File); > +log(llvm::toString(Contents.takeError())); > +return; > + } > > - // We only support
[clang-tools-extra] r328500 - [clangd] Support incremental document syncing
Author: simark Date: Mon Mar 26 07:41:40 2018 New Revision: 328500 URL: http://llvm.org/viewvc/llvm-project?rev=328500=rev Log: [clangd] Support incremental document syncing Summary: This patch adds support for incremental document syncing, as described in the LSP spec. The protocol specifies ranges in terms of Position (a line and a character), and our drafts are stored as plain strings. So I see two things that may not be super efficient for very large files: - Converting a Position to an offset (the positionToOffset function) requires searching for end of lines until we reach the desired line. - When we update a range, we construct a new string, which implies copying the whole document. However, for the typical size of a C++ document and the frequency of update (at which a user types), it may not be an issue. This patch aims at getting the basic feature in, and we can always improve it later if we find it's too slow. Signed-off-by: Simon MarchiReviewers: malaperle, ilya-biryukov Reviewed By: ilya-biryukov Subscribers: MaskRay, klimek, mgorny, ilya-biryukov, jkorous-apple, ioeric, cfe-commits Differential Revision: https://reviews.llvm.org/D44272 Added: clang-tools-extra/trunk/test/clangd/textdocument-didchange-fail.test clang-tools-extra/trunk/unittests/clangd/DraftStoreTests.cpp Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp clang-tools-extra/trunk/clangd/DraftStore.cpp clang-tools-extra/trunk/clangd/DraftStore.h clang-tools-extra/trunk/clangd/Protocol.cpp clang-tools-extra/trunk/clangd/Protocol.h clang-tools-extra/trunk/test/clangd/initialize-params-invalid.test clang-tools-extra/trunk/test/clangd/initialize-params.test clang-tools-extra/trunk/unittests/clangd/CMakeLists.txt Modified: clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp?rev=328500=328499=328500=diff == --- clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdLSPServer.cpp Mon Mar 26 07:41:40 2018 @@ -100,7 +100,7 @@ void ClangdLSPServer::onInitialize(Initi reply(json::obj{ {{"capabilities", json::obj{ -{"textDocumentSync", 1}, +{"textDocumentSync", (int)TextDocumentSyncKind::Incremental}, {"documentFormattingProvider", true}, {"documentRangeFormattingProvider", true}, {"documentOnTypeFormattingProvider", @@ -147,25 +147,30 @@ void ClangdLSPServer::onDocumentDidOpen( PathRef File = Params.textDocument.uri.file(); std::string = Params.textDocument.text; - DraftMgr.updateDraft(File, Contents); + DraftMgr.addDraft(File, Contents); Server.addDocument(File, Contents, WantDiagnostics::Yes); } void ClangdLSPServer::onDocumentDidChange(DidChangeTextDocumentParams ) { - if (Params.contentChanges.size() != 1) -return replyError(ErrorCode::InvalidParams, - "can only apply one change at a time"); auto WantDiags = WantDiagnostics::Auto; if (Params.wantDiagnostics.hasValue()) WantDiags = Params.wantDiagnostics.getValue() ? WantDiagnostics::Yes : WantDiagnostics::No; PathRef File = Params.textDocument.uri.file(); - std::string = Params.contentChanges[0].text; + llvm::Expected Contents = + DraftMgr.updateDraft(File, Params.contentChanges); + if (!Contents) { +// If this fails, we are most likely going to be not in sync anymore with +// the client. It is better to remove the draft and let further operations +// fail rather than giving wrong results. +DraftMgr.removeDraft(File); +Server.removeDocument(File); +log(llvm::toString(Contents.takeError())); +return; + } - // We only support full syncing right now. - DraftMgr.updateDraft(File, Contents); - Server.addDocument(File, Contents, WantDiags); + Server.addDocument(File, *Contents, WantDiags); } void ClangdLSPServer::onFileEvent(DidChangeWatchedFilesParams ) { Modified: clang-tools-extra/trunk/clangd/DraftStore.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/DraftStore.cpp?rev=328500=328499=328500=diff == --- clang-tools-extra/trunk/clangd/DraftStore.cpp (original) +++ clang-tools-extra/trunk/clangd/DraftStore.cpp Mon Mar 26 07:41:40 2018 @@ -8,6 +8,8 @@ //===--===// #include "DraftStore.h" +#include "SourceCode.h" +#include "llvm/Support/Errc.h" using namespace clang; using namespace clang::clangd; @@ -32,12 +34,72 @@ std::vector DraftStore::getActiveF return ResultVector; } -void DraftStore::updateDraft(PathRef File, StringRef Contents) { +void