njames93 updated this revision to Diff 315070. njames93 added a comment. Herald added a subscriber: javed.absar.
Use VFS instead of DraftStore Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D93978/new/ https://reviews.llvm.org/D93978 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/TUScheduler.h clang-tools-extra/clangd/refactor/Tweak.cpp clang-tools-extra/clangd/refactor/Tweak.h clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/tool/Check.cpp clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp
Index: clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp =================================================================== --- clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp +++ clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp @@ -74,7 +74,8 @@ SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Range.first, Range.second, [&](SelectionTree ST) { Tweak::Selection S(Index, AST, Range.first, - Range.second, std::move(ST)); + Range.second, std::move(ST), + nullptr); if (auto T = prepareTweak(TweakID, S)) { Result = (*T)->apply(S); return true; Index: clang-tools-extra/clangd/tool/Check.cpp =================================================================== --- clang-tools-extra/clangd/tool/Check.cpp +++ clang-tools-extra/clangd/tool/Check.cpp @@ -202,7 +202,8 @@ vlog(" {0} {1}", Pos, Tok.text(AST->getSourceManager())); auto Tree = SelectionTree::createRight(AST->getASTContext(), AST->getTokens(), Start, End); - Tweak::Selection Selection(&Index, *AST, Start, End, std::move(Tree)); + Tweak::Selection Selection(&Index, *AST, Start, End, std::move(Tree), + nullptr); for (const auto &T : prepareTweaks(Selection, Opts.TweakFilter)) { auto Result = T->apply(Selection); if (!Result) { Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp =================================================================== --- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -36,6 +36,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" +#include "llvm/Support/VirtualFileSystem.h" #include <cstddef> #include <string> @@ -63,10 +64,9 @@ } llvm::Optional<Path> getSourceFile(llvm::StringRef FileName, - const Tweak::Selection &Sel) { - if (auto Source = getCorrespondingHeaderOrSource( - FileName, - &Sel.AST->getSourceManager().getFileManager().getVirtualFileSystem())) + const Tweak::Selection &Sel, + llvm::vfs::FileSystem *FS) { + if (auto Source = getCorrespondingHeaderOrSource(FileName, FS)) return *Source; return getCorrespondingHeaderOrSource(FileName, *Sel.AST, Sel.Index); } @@ -403,13 +403,18 @@ if (!MainFileName) return error("Couldn't get absolute path for main file."); - auto CCFile = getSourceFile(*MainFileName, Sel); + // If we have a Filesystem attached to the Selection, use that, otherwise + // fallback to the SourceManagar Filesystem. + auto *FS = Sel.VFS ? Sel.VFS + : &Sel.AST->getSourceManager() + .getFileManager() + .getVirtualFileSystem(); + + auto CCFile = getSourceFile(*MainFileName, Sel, FS); + if (!CCFile) return error("Couldn't find a suitable implementation file."); - - auto &FS = - Sel.AST->getSourceManager().getFileManager().getVirtualFileSystem(); - auto Buffer = FS.getBufferForFile(*CCFile); + auto Buffer = FS->getBufferForFile(*CCFile); // FIXME: Maybe we should consider creating the implementation file if it // doesn't exist? if (!Buffer) Index: clang-tools-extra/clangd/refactor/Tweak.h =================================================================== --- clang-tools-extra/clangd/refactor/Tweak.h +++ clang-tools-extra/clangd/refactor/Tweak.h @@ -30,6 +30,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/VirtualFileSystem.h" #include <string> namespace clang { @@ -48,7 +49,8 @@ /// Input to prepare and apply tweaks. struct Selection { Selection(const SymbolIndex *Index, ParsedAST &AST, unsigned RangeBegin, - unsigned RangeEnd, SelectionTree ASTSelection); + unsigned RangeEnd, SelectionTree ASTSelection, + llvm::vfs::FileSystem *VFS); /// The text of the active document. llvm::StringRef Code; /// The Index for handling codebase related queries. @@ -64,6 +66,8 @@ unsigned SelectionEnd; /// The AST nodes that were selected. SelectionTree ASTSelection; + /// The file system that should be queried for cross file tweaks. + llvm::vfs::FileSystem *VFS = nullptr; // FIXME: provide a way to get sources and ASTs for other files. }; Index: clang-tools-extra/clangd/refactor/Tweak.cpp =================================================================== --- clang-tools-extra/clangd/refactor/Tweak.cpp +++ clang-tools-extra/clangd/refactor/Tweak.cpp @@ -47,9 +47,10 @@ Tweak::Selection::Selection(const SymbolIndex *Index, ParsedAST &AST, unsigned RangeBegin, unsigned RangeEnd, - SelectionTree ASTSelection) + SelectionTree ASTSelection, + llvm::vfs::FileSystem *VFS) : Index(Index), AST(&AST), SelectionBegin(RangeBegin), - SelectionEnd(RangeEnd), ASTSelection(std::move(ASTSelection)) { + SelectionEnd(RangeEnd), ASTSelection(std::move(ASTSelection)), VFS(VFS) { auto &SM = AST.getSourceManager(); Code = SM.getBufferData(SM.getMainFileID()); Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin); Index: clang-tools-extra/clangd/TUScheduler.h =================================================================== --- clang-tools-extra/clangd/TUScheduler.h +++ clang-tools-extra/clangd/TUScheduler.h @@ -239,6 +239,15 @@ /// Returns a snapshot of all file buffer contents, per last update(). llvm::StringMap<std::string> getAllFileContents() const; + /// Returns a Filesystem snapshot of all file buffer contents, per last + /// update(). + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> getAllFileContentsFS() const; + + /// Returns a Snapshot of all file buffer contents in a Filesystem overlayed + /// ontop of \p Base. + llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> overlayFileContents( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> Base) const; + /// Schedule an async task with no dependencies. /// Path may be empty (it is used only to set the Context). void run(llvm::StringRef Name, llvm::StringRef Path, Index: clang-tools-extra/clangd/TUScheduler.cpp =================================================================== --- clang-tools-extra/clangd/TUScheduler.cpp +++ clang-tools-extra/clangd/TUScheduler.cpp @@ -1456,5 +1456,26 @@ MT.detail(Elem.first()).child("ast").addUsage(Elem.second.UsedBytesAST); } } + +llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> +TUScheduler::getAllFileContentsFS() const { + // FIXME: Copying the files is needlessly expensive and grows according to how + // many files are being tracked, it may be worthwhile to create a Filesystem + // that references this and only copy the buffers lazily. + auto *InMemoryFS = new llvm::vfs::InMemoryFileSystem; + for (const auto &File : Files) + InMemoryFS->addFile( + File.first(), 0, + llvm::MemoryBuffer::getMemBufferCopy(File.getValue()->Contents)); + return InMemoryFS; +} + +llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> +TUScheduler::overlayFileContents( + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> Base) const { + auto *OverlayFS = new llvm::vfs::OverlayFileSystem(std::move(Base)); + OverlayFS->pushOverlay(getAllFileContentsFS()); + return OverlayFS; +} } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/ClangdServer.cpp =================================================================== --- clang-tools-extra/clangd/ClangdServer.cpp +++ clang-tools-extra/clangd/ClangdServer.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <chrono> @@ -429,7 +430,8 @@ // May generate several candidate selections, due to SelectionTree ambiguity. // vector of pointers because GCC doesn't like non-copyable Selection. static llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>> -tweakSelection(const Range &Sel, const InputsAndAST &AST) { +tweakSelection(const Range &Sel, const InputsAndAST &AST, + llvm::vfs::FileSystem *VFS = nullptr) { auto Begin = positionToOffset(AST.Inputs.Contents, Sel.start); if (!Begin) return Begin.takeError(); @@ -441,7 +443,7 @@ AST.AST.getASTContext(), AST.AST.getTokens(), *Begin, *End, [&](SelectionTree T) { Result.push_back(std::make_unique<Tweak::Selection>( - AST.Inputs.Index, AST.AST, *Begin, *End, std::move(T))); + AST.Inputs.Index, AST.AST, *Begin, *End, std::move(T), VFS)); return false; }); assert(!Result.empty() && "Expected at least one SelectionTree"); @@ -494,16 +496,17 @@ TweakAttempt.record(1, TweakID); auto Action = [File = File.str(), Sel, TweakID = TweakID.str(), CB = std::move(CB), + FS(WorkScheduler.overlayFileContents(TFS.view(llvm::None))), this](Expected<InputsAndAST> InpAST) mutable { if (!InpAST) return CB(InpAST.takeError()); - auto Selections = tweakSelection(Sel, *InpAST); + auto Selections = tweakSelection(Sel, *InpAST, FS.get()); if (!Selections) return CB(Selections.takeError()); llvm::Optional<llvm::Expected<Tweak::Effect>> Effect; // Try each selection, take the first one that prepare()s. // If they all fail, Effect will hold get the last error. - for (const auto &Selection : *Selections) { + for (auto &Selection : *Selections) { auto T = prepareTweak(TweakID, *Selection); if (T) { Effect = (*T)->apply(*Selection);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits