ilya-biryukov added a comment.

Thanks again. This generally looks LGTM, just a last drop of small nits. Will 
approve as soon as they land.



================
Comment at: clangd/DraftStore.cpp:75
+      return llvm::make_error<llvm::StringError>(
+          llvm::formatv("Range's end position (line={0}, character={1}) is "
+                        "before start position (line={2}, character={3}).",
----------------
Could we add a format provide for `Position` to make this formatting code 
shorter?
We'll need to define the corresponding specialization in `Protocol.h`:

```
namespace llvm {
  template <>
  struct format_provider<clang::clangd::Position> {
    static void format(const clang::clangd::Position &Pos, raw_ostream &OS, 
StringRef Style) { 
     assert(Style.empty() && "style modifiers for this type are not supported");
     OS << Pos;
    }
  };
}
```

This will allow to simplify this call site to:
```
llvm::formatv("Range's end position ({0}) is before start position ({1})", End, 
Start)
```


================
Comment at: clangd/DraftStore.cpp:100
+  EntryIt->second = Contents;
+  return std::move(Contents);
+}
----------------
Doing `return std::move(localvar)` is a pessimization. Use `return Contents;` 
instead.
 (for reference see 
[[https://stackoverflow.com/questions/14856344/when-should-stdmove-be-used-on-a-function-return-value|this
 SO post]], clang should give a warning for that case too)


================
Comment at: clangd/DraftStore.h:36
   /// Replace contents of the draft for \p File with \p Contents.
-  void updateDraft(PathRef File, StringRef Contents);
+  void addDraft(PathRef File, StringRef Contents);
+
----------------
simark wrote:
> ilya-biryukov wrote:
> > ilya-biryukov wrote:
> > > simark wrote:
> > > > ilya-biryukov wrote:
> > > > > Could we add versions from LSP's `VersionedTextDocumentIdentifier` 
> > > > > here and make the relevant sanity checks?
> > > > > Applying diffs to the wrong version will cause everything to fall 
> > > > > apart, so we should detect this error and signal it to the client as 
> > > > > soon as possible.
> > > > I agree that applying diffs to the wrong version will break basically 
> > > > everything, but even if we detect a version mismatch, I don't see what 
> > > > we could do, since we don't have a mean to report the error to the 
> > > > client.  The only thing we could do is log it (which we already do.
> > > If we couldn't apply a diff, we should return errors from all future 
> > > operations on this file until it gets closed and reopened. Otherwise 
> > > clangd and the editor would see inconsistent contents for the file and 
> > > results provided by clangd would be unreliable.
> > > The errors from any actions on the invalid file would actually be visible 
> > > to the users.
> > > 
> > > The simplest way to achieve that is to remove the file from `DraftStore` 
> > > and `ClangdServer` on errors from `updateDraft`.
> > > This will give "calling action on non-tracked file" errors for future 
> > > operations and the actual root cause can be figured out from the logs.
> > We still ignore version numbers from the LSP.
> > Is this another change that didn't get in?
> The more I think about it, the less sure I am that this is the intended usage 
> of the version.  The spec doesn't even say what the initial version of a file 
> should be, 0 or 1?  Then, it just says that the version optionally contained 
> in the `VersionedTextDocumentIdentifier` reflects the version of the document 
> after having applied the edit.  But I don't think we can predict and validate 
> what that version should be.  Most clients will probably just use a sequence 
> number, but I guess they don't have to...
> 
> Also, I initially assumed that having N changes in the `contentChanges` array 
> would mean that the version number would be bumped by N.  But now that I 
> re-read it, there's really nothing that says it should behave like this.
> 
> I think that we should just record the version number and treat it as opaque, 
> so that we can use it later when sending text edits to the client, for 
> example.  The client can then verify that the edit is for the same version of 
> the document that it has at the moment.
> 
> Therefore, I don't think it would really be useful in this patch.
The initial version is provided in `didOpen` (see `TextDocumentItem`).
I've also misread description of `contentChanges` in the same way. It's true 
that versions might grow by any  
[[https://github.com/Microsoft/language-server-protocol/issues/241|any positive 
number]], so we can't rely on them for the checks I propose here.
Thanks for looking into that and explaining the spec :-)


================
Comment at: clangd/DraftStore.h:26
 /// filenames. The contents are owned by the DraftStore.
 class DraftStore {
 public:
----------------
Could we also mention in the comment that this class now handles applying 
incremental document changes?


================
Comment at: unittests/clangd/DraftStoreTests.cpp:36
+/// Send the changes one by one to updateDraft, verify the intermediate 
results.
+static void stepByStep(llvm::ArrayRef<IncrementalTestStep> Steps) {
+  DraftStore DS;
----------------
NIT: another redundant static




================
Comment at: unittests/clangd/DraftStoreTests.cpp:62
+/// Send all the changes at once to updateDraft, check only the final result.
+static void allAtOnce(llvm::ArrayRef<IncrementalTestStep> Steps) {
+  DraftStore DS;
----------------
NIT: another redundant `static`


================
Comment at: unittests/clangd/DraftStoreTests.cpp:66
+  Annotations FinalSrc(Steps.back().Src);
+  const char Path[] = "/hello.cpp";
+  std::vector<TextDocumentContentChangeEvent> Changes;
----------------
NIT: another instance of `constexpr StringLiteral`


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44272



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to