Index: clangd/ClangdServer.h =================================================================== --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -82,16 +82,21 @@ class FileSystemProvider { public: virtual ~FileSystemProvider() = default; + /// Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing. + /// Name of the file that will be parsed is passed in \p File. + /// /// \return A filesystem that will be used for all file accesses in clangd. /// A Tag returned by this method will be propagated to all results of clangd /// that will use this filesystem. - virtual Tagged> getTaggedFileSystem() = 0; + virtual Tagged> + getTaggedFileSystem(PathRef File) = 0; }; class RealFileSystemProvider : public FileSystemProvider { public: /// \return getRealFileSystem() tagged with default tag, i.e. VFSTag() - Tagged> getTaggedFileSystem() override; + Tagged> + getTaggedFileSystem(PathRef File) override; }; class ClangdServer; Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -59,7 +59,7 @@ } Tagged> -RealFileSystemProvider::getTaggedFileSystem() { +RealFileSystemProvider::getTaggedFileSystem(PathRef File) { return make_tagged(vfs::getRealFileSystem(), VFSTag()); } @@ -156,7 +156,7 @@ assert(FileContents.Draft && "No contents inside a file that was scheduled for reparse"); - auto TaggedFS = FSProvider.getTaggedFileSystem(); + auto TaggedFS = FSProvider.getTaggedFileSystem(FileStr); Units.runOnUnit( FileStr, *FileContents.Draft, CDB, PCHs, TaggedFS.Value, [&](ClangdUnit const &Unit) { @@ -197,7 +197,7 @@ } std::vector Result; - auto TaggedFS = FSProvider.getTaggedFileSystem(); + auto TaggedFS = FSProvider.getTaggedFileSystem(File); // It would be nice to use runOnUnitWithoutReparse here, but we can't // guarantee the correctness of code completion cache here if we don't do the // reparse. Index: unittests/clangd/ClangdTests.cpp =================================================================== --- unittests/clangd/ClangdTests.cpp +++ unittests/clangd/ClangdTests.cpp @@ -172,9 +172,13 @@ class MockFSProvider : public FileSystemProvider { public: - Tagged> getTaggedFileSystem() override { + Tagged> + getTaggedFileSystem(PathRef File) override { IntrusiveRefCntPtr MemFS( new vfs::InMemoryFileSystem); + if (ExpectedFile) + EXPECT_EQ(*ExpectedFile, File); + for (auto &FileAndContents : Files) MemFS->addFile(FileAndContents.first(), time_t(), llvm::MemoryBuffer::getMemBuffer(FileAndContents.second, @@ -186,6 +190,7 @@ return make_tagged(OverlayFS, Tag); } + llvm::Optional> ExpectedFile; llvm::StringMap Files; VFSTag Tag = VFSTag(); }; @@ -248,7 +253,10 @@ FileWithContents.second; auto SourceFilename = getVirtualTestFilePath(SourceFileRelPath); + + FS.ExpectedFile = SourceFilename; Server.addDocument(SourceFilename, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, SourceFilename); EXPECT_EQ(ExpectErrors, DiagConsumer.hadErrorInLastDiags()); return Result; @@ -307,6 +315,7 @@ FS.Files[FooH] = "int a;"; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); @@ -342,6 +351,7 @@ FS.Files[FooH] = "int a;"; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents); auto DumpParse1 = dumpASTWithoutMemoryLocs(Server, FooCpp); @@ -371,8 +381,9 @@ auto FooCpp = getVirtualTestFilePath("foo.cpp"); const auto SourceContents = "int a;"; FS.Files[FooCpp] = SourceContents; - FS.Tag = "123"; + FS.ExpectedFile = FooCpp; + FS.Tag = "123"; Server.addDocument(FooCpp, SourceContents); EXPECT_EQ(DiagConsumer.lastVFSTag(), FS.Tag); EXPECT_EQ(Server.codeComplete(FooCpp, Position{0, 0}).Tag, FS.Tag); @@ -419,6 +430,7 @@ // miss). Position CompletePos = {2, 8}; FS.Files[FooCpp] = SourceContents; + FS.ExpectedFile = FooCpp; Server.addDocument(FooCpp, SourceContents);