clang-tools 8.0.0

FS.cpp
Go to the documentation of this file.
1 //===--- FS.cpp - File system related utils ----------------------*- 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 "FS.h"
11 #include "clang/Basic/LLVM.h"
12 #include "llvm/ADT/None.h"
13 #include "llvm/Support/Path.h"
14
15 namespace clang {
16 namespace clangd {
17
18 PreambleFileStatusCache::PreambleFileStatusCache(llvm::StringRef MainFilePath)
19 : MainFilePath(MainFilePath) {
20 assert(llvm::sys::path::is_absolute(MainFilePath));
21 }
22
23 void PreambleFileStatusCache::update(const llvm::vfs::FileSystem &FS,
24 llvm::vfs::Status S) {
25 llvm::SmallString<32> PathStore(S.getName());
26 if (FS.makeAbsolute(PathStore))
27 return;
28 // Do not cache status for the main file.
29 if (PathStore == MainFilePath)
30 return;
31 // Stores the latest status in cache as it can change in a preamble build.
32 StatCache.insert({PathStore, std::move(S)});
33 }
34
35 llvm::Optional<llvm::vfs::Status>
36 PreambleFileStatusCache::lookup(llvm::StringRef File) const {
37 auto I = StatCache.find(File);
38 if (I != StatCache.end())
39 return I->getValue();
40 return None;
41 }
42
43 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
44 PreambleFileStatusCache::getProducingFS(
45 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) {
46 // This invalidates old status in cache if files are re-`open()`ed or
47 // re-`stat()`ed in case file status has changed during preamble build.
48 class CollectFS : public llvm::vfs::ProxyFileSystem {
49 public:
50 CollectFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
51 PreambleFileStatusCache &StatCache)
52 : ProxyFileSystem(std::move(FS)), StatCache(StatCache) {}
53
54 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
55 openFileForRead(const llvm::Twine &Path) override {
56 auto File = getUnderlyingFS().openFileForRead(Path);
57 if (!File || !*File)
58 return File;
59 // Eagerly stat opened file, as the followup `status` call on the file
60 // doesn't necessarily go through this FS. This puts some extra work on
61 // preamble build, but it should be worth it as preamble can be reused
62 // many times (e.g. code completion) and the repeated status call is
63 // likely to be cached in the underlying file system anyway.
64 if (auto S = File->get()->status())
65 StatCache.update(getUnderlyingFS(), std::move(*S));
66 return File;
67 }
68
69 llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override {
70 auto S = getUnderlyingFS().status(Path);
71 if (S)
72 StatCache.update(getUnderlyingFS(), *S);
73 return S;
74 }
75
76 private:
77 PreambleFileStatusCache &StatCache;
78 };
79 return llvm::IntrusiveRefCntPtr<CollectFS>(
80 new CollectFS(std::move(FS), *this));
81 }
82
83 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
84 PreambleFileStatusCache::getConsumingFS(
85 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) const {
86 class CacheVFS : public llvm::vfs::ProxyFileSystem {
87 public:
88 CacheVFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
89 const PreambleFileStatusCache &StatCache)
90 : ProxyFileSystem(std::move(FS)), StatCache(StatCache) {}
91
92 llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override {
93 if (auto S = StatCache.lookup(Path.str()))
94 return *S;
95 return getUnderlyingFS().status(Path);
96 }
97
98 private:
99 const PreambleFileStatusCache &StatCache;
100 };
101 return llvm::IntrusiveRefCntPtr<CacheVFS>(new CacheVFS(std::move(FS), *this));
102 }
103
104 } // namespace clangd
105 } // namespace clang
clang::clangd::PreambleFileStatusCache::update
void update(const llvm::vfs::FileSystem &FS, llvm::vfs::Status S)
Definition: FS.cpp:23
clang::clangd::PreambleFileStatusCache::lookup
llvm::Optional< llvm::vfs::Status > lookup(llvm::StringRef Path) const
Path is a path stored in preamble.
Definition: FS.cpp:36
clang::clangd::PreambleFileStatusCache::PreambleFileStatusCache
PreambleFileStatusCache(llvm::StringRef MainFilePath)
MainFilePath is the absolute path of the main source file this preamble corresponds to...
Definition: FS.cpp:18
clang::clangd::TextDocumentSyncKind::None
Documents should not be synced at all.
clang::clangd::PreambleFileStatusCache::getConsumingFS
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getConsumingFS(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS) const
Returns a VFS that uses the cache collected.
Definition: FS.cpp:84
clang::clangd::PreambleFileStatusCache::getProducingFS
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getProducingFS(IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
Returns a VFS that collects file status.
Definition: FS.cpp:44
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:21
clang::clangd::PreambleFileStatusCache
Records status information for files open()ed or stat()ed during preamble build (except for the main ...
Definition: FS.h:37
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
clang::clangd::CompletionItemKind::File
FS.h