[PATCH] D44272: [clangd] Support incremental document syncing
Simon Marchi via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 19 10:32:26 PDT 2018
simark marked 3 inline comments as done.
simark added inline comments.
================
Comment at: clangd/DraftStore.cpp:61
+ const Position &Start = Change.range->start;
+ size_t StartIndex = positionToOffset(Contents, Start);
+ if (StartIndex > Contents.length()) {
----------------
ilya-biryukov wrote:
> `positionToOffset` always truncates to size of contents. It has to return `Expected<int>` too here.
Indeed, it would be better.
================
Comment at: clangd/DraftStore.cpp:73
+ if (EndIndex > Contents.length()) {
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Range's end position (line={0}, character={1}) is "
----------------
ilya-biryukov wrote:
> Having partially applied changes in the map seems weird. Maybe the code applying the diffs to a separate function that returns either new contents or an error and use it here?
> I.e. we won't be able to end up in a state with partially applied changes:
>
> ```
> Expected<string> applyChanges(StringRef Contents, ArrayRef<TextDocumentChange> Changes) {
> }
>
> // See other comment about Version.
> Expected<string> updateDraft(StringRef File, /*int Version,*/ ArrayRef<TextDocumentChange> Changes) {
> // check File is in the map and version matches....
> //...
> string& Contents = ...;
> auto NewContents = applyChanges(Contents, Changes);
> if (!NewContents)
> return NewContents.takeError();
> Contents = *NewContents;
> return std::move(*NewContents);
> }
> ```
It makes sense, but I think we can achieve the same result by just tweaking the current code. I don't think a separate function is really needed here.
================
Comment at: clangd/DraftStore.cpp:97
+
+ NewContents.reserve(StartIndex + Change.text.length() +
+ (Contents.length() - EndIndex));
----------------
ilya-biryukov wrote:
> The math is correct, but I'm confused on how to properly read the formula here.
> Maybe change to:
> `Contents.length() - (EndIndex - StartIndex) + Change.text.length()`?
>
> This clearly reads as:
> `LengthBefore - LengthRemoved + LengthAdded`
I saw it as `LengthOfTheSliceFromTheOriginalThatWeKeepBefore + LengthOfNewStuff + LengthOfTheSliceFromTheOriginalThatWeKeepAfter`. But I don't mind changing it.
================
Comment at: clangd/DraftStore.cpp:103
+
+ if (EndIndex < Contents.length())
+ NewContents += Contents.substr(EndIndex);
----------------
ilya-biryukov wrote:
> This check seems unnecessary, we've already checked for range errors. Maybe remove it?
Note that this check is not equivalent to the previous
if (EndIndex > Contents.length())
for the case where `EndIndex == Contents.length()`. In our case, it's possible (and valid) for EndIndex to be equal to Contents.length(), when referring to the end of the document (past the last character). I thought that doing `Contents.substr(Contents.length())` would be throw `std::out_of_range` or be undefined behavior, but now that I read it correctly:
@throw std::out_of_range If __pos > size().
So it looks like it would fine to have pos == Contents.length().
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D44272
More information about the cfe-commits
mailing list