clang-tools  7.0.0
DraftStore.cpp
Go to the documentation of this file.
1 //===--- DraftStore.cpp - File contents container ---------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "DraftStore.h"
11 #include "SourceCode.h"
12 #include "llvm/Support/Errc.h"
13 
14 using namespace clang;
15 using namespace clang::clangd;
16 
17 llvm::Optional<std::string> DraftStore::getDraft(PathRef File) const {
18  std::lock_guard<std::mutex> Lock(Mutex);
19 
20  auto It = Drafts.find(File);
21  if (It == Drafts.end())
22  return llvm::None;
23 
24  return It->second;
25 }
26 
27 std::vector<Path> DraftStore::getActiveFiles() const {
28  std::lock_guard<std::mutex> Lock(Mutex);
29  std::vector<Path> ResultVector;
30 
31  for (auto DraftIt = Drafts.begin(); DraftIt != Drafts.end(); DraftIt++)
32  ResultVector.push_back(DraftIt->getKey());
33 
34  return ResultVector;
35 }
36 
38  std::lock_guard<std::mutex> Lock(Mutex);
39 
40  Drafts[File] = Contents;
41 }
42 
43 llvm::Expected<std::string> DraftStore::updateDraft(
44  PathRef File, llvm::ArrayRef<TextDocumentContentChangeEvent> Changes) {
45  std::lock_guard<std::mutex> Lock(Mutex);
46 
47  auto EntryIt = Drafts.find(File);
48  if (EntryIt == Drafts.end()) {
49  return llvm::make_error<llvm::StringError>(
50  "Trying to do incremental update on non-added document: " + File,
51  llvm::errc::invalid_argument);
52  }
53 
54  std::string Contents = EntryIt->second;
55 
56  for (const TextDocumentContentChangeEvent &Change : Changes) {
57  if (!Change.range) {
58  Contents = Change.text;
59  continue;
60  }
61 
62  const Position &Start = Change.range->start;
63  llvm::Expected<size_t> StartIndex =
64  positionToOffset(Contents, Start, false);
65  if (!StartIndex)
66  return StartIndex.takeError();
67 
68  const Position &End = Change.range->end;
69  llvm::Expected<size_t> EndIndex = positionToOffset(Contents, End, false);
70  if (!EndIndex)
71  return EndIndex.takeError();
72 
73  if (*EndIndex < *StartIndex)
74  return llvm::make_error<llvm::StringError>(
75  llvm::formatv(
76  "Range's end position ({0}) is before start position ({1})", End,
77  Start),
78  llvm::errc::invalid_argument);
79 
80  if (Change.rangeLength &&
81  (ssize_t)(*EndIndex - *StartIndex) != *Change.rangeLength)
82  return llvm::make_error<llvm::StringError>(
83  llvm::formatv("Change's rangeLength ({0}) doesn't match the "
84  "computed range length ({1}).",
85  *Change.rangeLength, *EndIndex - *StartIndex),
86  llvm::errc::invalid_argument);
87 
88  std::string NewContents;
89  NewContents.reserve(*StartIndex + Change.text.length() +
90  (Contents.length() - *EndIndex));
91 
92  NewContents = Contents.substr(0, *StartIndex);
93  NewContents += Change.text;
94  NewContents += Contents.substr(*EndIndex);
95 
96  Contents = std::move(NewContents);
97  }
98 
99  EntryIt->second = Contents;
100  return Contents;
101 }
102 
104  std::lock_guard<std::mutex> Lock(Mutex);
105 
106  Drafts.erase(File);
107 }
llvm::Expected< std::string > updateDraft(PathRef File, llvm::ArrayRef< TextDocumentContentChangeEvent > Changes)
Update the contents of the draft for File based on Changes.
Definition: DraftStore.cpp:43
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:24
Documents should not be synced at all.
StringRef Contents
void addDraft(PathRef File, StringRef Contents)
Replace contents of the draft for File with Contents.
Definition: DraftStore.cpp:37
llvm::Expected< size_t > positionToOffset(StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Definition: SourceCode.cpp:83
llvm::Optional< std::string > getDraft(PathRef File) const
Definition: DraftStore.cpp:17
std::vector< Path > getActiveFiles() const
Definition: DraftStore.cpp:27
void removeDraft(PathRef File)
Remove the draft from the store.
Definition: DraftStore.cpp:103
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//