mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 11:36:41 +00:00
[clangd] Rename FSProvider to TFS in case of ThreadsafeFS
Summary: Depends on D81998 Reviewers: sammccall Subscribers: ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82024
This commit is contained in:
parent
0628705efa
commit
8d654df5b9
@ -524,7 +524,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
|
||||
if (NegotiatedOffsetEncoding)
|
||||
WithOffsetEncoding.emplace(kCurrentOffsetEncoding,
|
||||
*NegotiatedOffsetEncoding);
|
||||
Server.emplace(*CDB, FSProvider, ClangdServerOpts,
|
||||
Server.emplace(*CDB, TFS, ClangdServerOpts,
|
||||
static_cast<ClangdServer::Callbacks *>(this));
|
||||
}
|
||||
applyConfiguration(Params.initializationOptions.ConfigSettings);
|
||||
@ -1340,16 +1340,15 @@ void ClangdLSPServer::onSemanticTokensEdits(
|
||||
}
|
||||
|
||||
ClangdLSPServer::ClangdLSPServer(
|
||||
class Transport &Transp, const ThreadsafeFS &FSProvider,
|
||||
class Transport &Transp, const ThreadsafeFS &TFS,
|
||||
const clangd::CodeCompleteOptions &CCOpts,
|
||||
const clangd::RenameOptions &RenameOpts,
|
||||
llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
|
||||
llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
|
||||
const ClangdServer::Options &Opts)
|
||||
: BackgroundContext(Context::current().clone()), Transp(Transp),
|
||||
MsgHandler(new MessageHandler(*this)), FSProvider(FSProvider),
|
||||
CCOpts(CCOpts), RenameOpts(RenameOpts),
|
||||
SupportedSymbolKinds(defaultSymbolKinds()),
|
||||
MsgHandler(new MessageHandler(*this)), TFS(TFS), CCOpts(CCOpts),
|
||||
RenameOpts(RenameOpts), SupportedSymbolKinds(defaultSymbolKinds()),
|
||||
SupportedCompletionItemKinds(defaultCompletionItemKinds()),
|
||||
UseDirBasedCDB(UseDirBasedCDB),
|
||||
CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts),
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
/// for compile_commands.json in all parent directories of each file.
|
||||
/// If UseDirBasedCDB is false, compile commands are not read from disk.
|
||||
// FIXME: Clean up signature around CDBs.
|
||||
ClangdLSPServer(Transport &Transp, const ThreadsafeFS &FSProvider,
|
||||
ClangdLSPServer(Transport &Transp, const ThreadsafeFS &TFS,
|
||||
const clangd::CodeCompleteOptions &CCOpts,
|
||||
const clangd::RenameOptions &RenameOpts,
|
||||
llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
|
||||
@ -207,7 +207,7 @@ private:
|
||||
notify("$/progress", Params);
|
||||
}
|
||||
|
||||
const ThreadsafeFS &FSProvider;
|
||||
const ThreadsafeFS &TFS;
|
||||
/// Options used for code completion
|
||||
clangd::CodeCompleteOptions CCOpts;
|
||||
/// Options used for rename.
|
||||
|
@ -130,9 +130,9 @@ ClangdServer::Options::operator TUScheduler::Options() const {
|
||||
}
|
||||
|
||||
ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
|
||||
const ThreadsafeFS &FSProvider, const Options &Opts,
|
||||
const ThreadsafeFS &TFS, const Options &Opts,
|
||||
Callbacks *Callbacks)
|
||||
: FSProvider(FSProvider),
|
||||
: TFS(TFS),
|
||||
DynamicIdx(Opts.BuildDynamicSymbolIndex
|
||||
? new FileIndex(Opts.HeavyweightDynamicSymbolIndex)
|
||||
: nullptr),
|
||||
@ -163,7 +163,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
|
||||
AddIndex(Opts.StaticIndex);
|
||||
if (Opts.BackgroundIndex) {
|
||||
BackgroundIdx = std::make_unique<BackgroundIndex>(
|
||||
Context::current().clone(), FSProvider, CDB,
|
||||
Context::current().clone(), TFS, CDB,
|
||||
BackgroundIndexStorage::createDiskBackedStorageFactory(
|
||||
[&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); }),
|
||||
std::max(Opts.AsyncThreadsCount, 1u),
|
||||
@ -185,12 +185,12 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
|
||||
// FIXME: call tidy options builder on the worker thread, it can do IO.
|
||||
if (GetClangTidyOptions)
|
||||
Opts.ClangTidyOpts =
|
||||
GetClangTidyOptions(*FSProvider.view(/*CWD=*/llvm::None), File);
|
||||
GetClangTidyOptions(*TFS.view(/*CWD=*/llvm::None), File);
|
||||
Opts.SuggestMissingIncludes = SuggestMissingIncludes;
|
||||
|
||||
// Compile command is set asynchronously during update, as it can be slow.
|
||||
ParseInputs Inputs;
|
||||
Inputs.FSProvider = &FSProvider;
|
||||
Inputs.TFS = &TFS;
|
||||
Inputs.Contents = std::string(Contents);
|
||||
Inputs.Version = Version.str();
|
||||
Inputs.ForceRebuild = ForceRebuild;
|
||||
@ -237,7 +237,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
|
||||
}
|
||||
}
|
||||
}
|
||||
ParseInputs ParseInput{IP->Command, &FSProvider, IP->Contents.str()};
|
||||
ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()};
|
||||
ParseInput.Index = Index;
|
||||
ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
|
||||
ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
|
||||
@ -284,7 +284,7 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos,
|
||||
return CB(llvm::createStringError(llvm::inconvertibleErrorCode(),
|
||||
"Failed to parse includes"));
|
||||
|
||||
ParseInputs ParseInput{IP->Command, &FSProvider, IP->Contents.str()};
|
||||
ParseInputs ParseInput{IP->Command, &TFS, IP->Contents.str()};
|
||||
ParseInput.Index = Index;
|
||||
ParseInput.Opts.BuildRecoveryAST = BuildRecoveryAST;
|
||||
ParseInput.Opts.PreserveRecoveryASTType = PreserveRecoveryASTType;
|
||||
@ -321,7 +321,7 @@ ClangdServer::formatOnType(llvm::StringRef Code, PathRef File, Position Pos,
|
||||
return CursorPos.takeError();
|
||||
auto Style = format::getStyle(format::DefaultFormatStyle, File,
|
||||
format::DefaultFallbackStyle, Code,
|
||||
FSProvider.view(/*CWD=*/llvm::None).get());
|
||||
TFS.view(/*CWD=*/llvm::None).get());
|
||||
if (!Style)
|
||||
return Style.takeError();
|
||||
|
||||
@ -398,7 +398,7 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
|
||||
|
||||
if (Opts.WantFormat) {
|
||||
auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
|
||||
*InpAST->Inputs.FSProvider);
|
||||
*InpAST->Inputs.TFS);
|
||||
llvm::Error Err = llvm::Error::success();
|
||||
for (auto &E : *Edits)
|
||||
Err =
|
||||
@ -499,7 +499,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
|
||||
for (auto &It : (*Effect)->ApplyEdits) {
|
||||
Edit &E = It.second;
|
||||
format::FormatStyle Style =
|
||||
getFormatStyleForFile(File, E.InitialCode, FSProvider);
|
||||
getFormatStyleForFile(File, E.InitialCode, TFS);
|
||||
if (llvm::Error Err = reformatEdit(E, Style))
|
||||
elog("Failed to format {0}: {1}", It.first(), std::move(Err));
|
||||
}
|
||||
@ -550,7 +550,7 @@ void ClangdServer::switchSourceHeader(
|
||||
// 2) if 1) fails, we use the AST&Index approach, it is slower but supports
|
||||
// different code layout.
|
||||
if (auto CorrespondingFile = getCorrespondingHeaderOrSource(
|
||||
std::string(Path), FSProvider.view(llvm::None)))
|
||||
std::string(Path), TFS.view(llvm::None)))
|
||||
return CB(std::move(CorrespondingFile));
|
||||
auto Action = [Path = Path.str(), CB = std::move(CB),
|
||||
this](llvm::Expected<InputsAndAST> InpAST) mutable {
|
||||
@ -565,7 +565,7 @@ llvm::Expected<tooling::Replacements>
|
||||
ClangdServer::formatCode(llvm::StringRef Code, PathRef File,
|
||||
llvm::ArrayRef<tooling::Range> Ranges) {
|
||||
// Call clang-format.
|
||||
format::FormatStyle Style = getFormatStyleForFile(File, Code, FSProvider);
|
||||
format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS);
|
||||
tooling::Replacements IncludeReplaces =
|
||||
format::sortIncludes(Style, Code, Ranges, File);
|
||||
auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
|
||||
@ -598,7 +598,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
|
||||
if (!InpAST)
|
||||
return CB(InpAST.takeError());
|
||||
format::FormatStyle Style = getFormatStyleForFile(
|
||||
File, InpAST->Inputs.Contents, *InpAST->Inputs.FSProvider);
|
||||
File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS);
|
||||
CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
|
||||
};
|
||||
|
||||
|
@ -171,9 +171,8 @@ public:
|
||||
/// added file (i.e., when processing a first call to addDocument) and reuses
|
||||
/// those arguments for subsequent reparses. However, ClangdServer will check
|
||||
/// if compilation arguments changed on calls to forceReparse().
|
||||
ClangdServer(const GlobalCompilationDatabase &CDB,
|
||||
const ThreadsafeFS &FSProvider, const Options &Opts,
|
||||
Callbacks *Callbacks = nullptr);
|
||||
ClangdServer(const GlobalCompilationDatabase &CDB, const ThreadsafeFS &TFS,
|
||||
const Options &Opts, Callbacks *Callbacks = nullptr);
|
||||
|
||||
/// Add a \p File to the list of tracked C++ files or update the contents if
|
||||
/// \p File is already tracked. Also schedules parsing of the AST for it on a
|
||||
@ -330,7 +329,7 @@ private:
|
||||
formatCode(llvm::StringRef Code, PathRef File,
|
||||
ArrayRef<tooling::Range> Ranges);
|
||||
|
||||
const ThreadsafeFS &FSProvider;
|
||||
const ThreadsafeFS &TFS;
|
||||
|
||||
Path ResourceDir;
|
||||
// The index used to look up symbols. This could be:
|
||||
|
@ -1113,8 +1113,7 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
|
||||
// NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
|
||||
// the remapped buffers do not get freed.
|
||||
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
|
||||
Input.ParseInput.FSProvider->view(
|
||||
Input.ParseInput.CompileCommand.Directory);
|
||||
Input.ParseInput.TFS->view(Input.ParseInput.CompileCommand.Directory);
|
||||
if (Input.Preamble.StatCache)
|
||||
VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS));
|
||||
auto Clang = prepareCompilerInstance(
|
||||
@ -1292,7 +1291,7 @@ public:
|
||||
IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
|
||||
auto Style = getFormatStyleForFile(SemaCCInput.FileName,
|
||||
SemaCCInput.ParseInput.Contents,
|
||||
*SemaCCInput.ParseInput.FSProvider);
|
||||
*SemaCCInput.ParseInput.TFS);
|
||||
const auto NextToken = Lexer::findNextToken(
|
||||
Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
|
||||
Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
|
||||
@ -1364,7 +1363,7 @@ public:
|
||||
}
|
||||
|
||||
CodeCompleteResult runWithoutSema(llvm::StringRef Content, size_t Offset,
|
||||
const ThreadsafeFS &FSProvider) && {
|
||||
const ThreadsafeFS &TFS) && {
|
||||
trace::Span Tracer("CodeCompleteWithoutSema");
|
||||
// Fill in fields normally set by runWithSema()
|
||||
HeuristicPrefix = guessCompletionPrefix(Content, Offset);
|
||||
@ -1380,7 +1379,7 @@ public:
|
||||
ProxSources[FileName].Cost = 0;
|
||||
FileProximity.emplace(ProxSources);
|
||||
|
||||
auto Style = getFormatStyleForFile(FileName, Content, FSProvider);
|
||||
auto Style = getFormatStyleForFile(FileName, Content, TFS);
|
||||
// This will only insert verbatim headers.
|
||||
Inserter.emplace(FileName, Content, Style,
|
||||
/*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
|
||||
@ -1781,7 +1780,7 @@ CodeCompleteResult codeComplete(PathRef FileName, Position Pos,
|
||||
SpecFuzzyFind, Opts);
|
||||
return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
|
||||
? std::move(Flow).runWithoutSema(ParseInput.Contents, *Offset,
|
||||
*ParseInput.FSProvider)
|
||||
*ParseInput.TFS)
|
||||
: std::move(Flow).run({FileName, *Offset, *Preamble,
|
||||
// We want to serve code completions with
|
||||
// low latency, so don't bother patching.
|
||||
|
@ -48,7 +48,7 @@ buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
|
||||
for (const auto &S : Inputs.CompileCommand.CommandLine)
|
||||
ArgStrs.push_back(S.c_str());
|
||||
|
||||
auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory);
|
||||
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
|
||||
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
|
||||
CompilerInstance::createDiagnostics(new DiagnosticOptions, &D, false);
|
||||
std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine(
|
||||
|
@ -46,7 +46,7 @@ struct ParseOptions {
|
||||
/// Information required to run clang, e.g. to parse AST or do code completion.
|
||||
struct ParseInputs {
|
||||
tooling::CompileCommand CompileCommand;
|
||||
const ThreadsafeFS *FSProvider;
|
||||
const ThreadsafeFS *TFS;
|
||||
std::string Contents;
|
||||
// Version identifier for Contents, provided by the client and opaque to us.
|
||||
std::string Version = "null";
|
||||
|
@ -249,7 +249,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
|
||||
trace::Span Tracer("BuildAST");
|
||||
SPAN_ATTACH(Tracer, "File", Filename);
|
||||
|
||||
auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory);
|
||||
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
|
||||
if (Preamble && Preamble->StatCache)
|
||||
VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
|
||||
|
||||
@ -355,8 +355,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
|
||||
auto BuildDir = VFS->getCurrentWorkingDirectory();
|
||||
if (Inputs.Opts.SuggestMissingIncludes && Inputs.Index &&
|
||||
!BuildDir.getError()) {
|
||||
auto Style =
|
||||
getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.FSProvider);
|
||||
auto Style = getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS);
|
||||
auto Inserter = std::make_shared<IncludeInserter>(
|
||||
Filename, Inputs.Contents, Style, BuildDir.get(),
|
||||
&Clang->getPreprocessor().getHeaderSearchInfo());
|
||||
|
@ -252,7 +252,7 @@ scanPreamble(llvm::StringRef Contents,
|
||||
// Build and run Preprocessor over the preamble.
|
||||
ParseInputs PI;
|
||||
PI.Contents = Contents.str();
|
||||
PI.FSProvider = FSProvider.get();
|
||||
PI.TFS = FSProvider.get();
|
||||
PI.CompileCommand = Cmd;
|
||||
IgnoringDiagConsumer IgnoreDiags;
|
||||
auto CI = buildCompilerInvocation(PI, IgnoreDiags);
|
||||
@ -358,7 +358,7 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
|
||||
CI.getPreprocessorOpts().WriteCommentListToPCH = false;
|
||||
|
||||
CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
|
||||
auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory);
|
||||
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
|
||||
llvm::SmallString<32> AbsFileName(FileName);
|
||||
VFS->makeAbsolute(AbsFileName);
|
||||
auto StatCache = std::make_unique<PreambleFileStatusCache>(AbsFileName);
|
||||
@ -395,7 +395,7 @@ bool isPreambleCompatible(const PreambleData &Preamble,
|
||||
llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName);
|
||||
auto Bounds =
|
||||
ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
|
||||
auto VFS = Inputs.FSProvider->view(Inputs.CompileCommand.Directory);
|
||||
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
|
||||
return compileCommandsAreEqual(Inputs.CompileCommand,
|
||||
Preamble.CompileCommand) &&
|
||||
Preamble.Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
|
||||
@ -423,7 +423,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
|
||||
SPAN_ATTACH(Tracer, "File", FileName);
|
||||
assert(llvm::sys::path::is_absolute(FileName) && "relative FileName!");
|
||||
auto VFS = Baseline.StatCache->getConsumingFS(
|
||||
Modified.FSProvider->view(/*CWD=*/llvm::None));
|
||||
Modified.TFS->view(/*CWD=*/llvm::None));
|
||||
// First scan preprocessor directives in Baseline and Modified. These will be
|
||||
// used to figure out newly added directives in Modified. Scanning can fail,
|
||||
// the code just bails out and creates an empty patch in such cases, as:
|
||||
|
@ -577,10 +577,10 @@ llvm::Optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {
|
||||
|
||||
format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
|
||||
llvm::StringRef Content,
|
||||
const ThreadsafeFS &FSProvider) {
|
||||
const ThreadsafeFS &TFS) {
|
||||
auto Style = format::getStyle(format::DefaultFormatStyle, File,
|
||||
format::DefaultFallbackStyle, Content,
|
||||
FSProvider.view(/*CWD=*/llvm::None).get());
|
||||
TFS.view(/*CWD=*/llvm::None).get());
|
||||
if (!Style) {
|
||||
log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.", File,
|
||||
Style.takeError());
|
||||
|
@ -168,7 +168,7 @@ llvm::Optional<std::string> getCanonicalPath(const FileEntry *F,
|
||||
/// though the latter may have been overridden in main()!
|
||||
format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
|
||||
llvm::StringRef Content,
|
||||
const ThreadsafeFS &FSProvider);
|
||||
const ThreadsafeFS &TFS);
|
||||
|
||||
/// Cleanup and format the given replacements.
|
||||
llvm::Expected<tooling::Replacements>
|
||||
|
@ -90,11 +90,11 @@ bool shardIsStale(const LoadedShard &LS, llvm::vfs::FileSystem *FS) {
|
||||
} // namespace
|
||||
|
||||
BackgroundIndex::BackgroundIndex(
|
||||
Context BackgroundContext, const ThreadsafeFS &FSProvider,
|
||||
Context BackgroundContext, const ThreadsafeFS &TFS,
|
||||
const GlobalCompilationDatabase &CDB,
|
||||
BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize,
|
||||
std::function<void(BackgroundQueue::Stats)> OnProgress)
|
||||
: SwapIndex(std::make_unique<MemIndex>()), FSProvider(FSProvider), CDB(CDB),
|
||||
: SwapIndex(std::make_unique<MemIndex>()), TFS(TFS), CDB(CDB),
|
||||
BackgroundContext(std::move(BackgroundContext)),
|
||||
Rebuilder(this, &IndexedSymbols, ThreadPoolSize),
|
||||
IndexStorageFactory(std::move(IndexStorageFactory)),
|
||||
@ -244,7 +244,7 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
|
||||
SPAN_ATTACH(Tracer, "file", Cmd.Filename);
|
||||
auto AbsolutePath = getAbsolutePath(Cmd);
|
||||
|
||||
auto FS = FSProvider.view(Cmd.Directory);
|
||||
auto FS = TFS.view(Cmd.Directory);
|
||||
auto Buf = FS->getBufferForFile(AbsolutePath);
|
||||
if (!Buf)
|
||||
return llvm::errorCodeToError(Buf.getError());
|
||||
@ -259,7 +259,7 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
|
||||
|
||||
vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
|
||||
ParseInputs Inputs;
|
||||
Inputs.FSProvider = &FSProvider;
|
||||
Inputs.TFS = &TFS;
|
||||
Inputs.CompileCommand = std::move(Cmd);
|
||||
IgnoreDiagnostics IgnoreDiags;
|
||||
auto CI = buildCompilerInvocation(Inputs, IgnoreDiags);
|
||||
@ -381,7 +381,7 @@ BackgroundIndex::loadProject(std::vector<std::string> MainFiles) {
|
||||
Rebuilder.loadedShard(LoadedShards);
|
||||
Rebuilder.doneLoading();
|
||||
|
||||
auto FS = FSProvider.view(/*CWD=*/llvm::None);
|
||||
auto FS = TFS.view(/*CWD=*/llvm::None);
|
||||
llvm::DenseSet<PathRef> TUsToIndex;
|
||||
// We'll accept data from stale shards, but ensure the files get reindexed
|
||||
// soon.
|
||||
|
@ -178,7 +178,7 @@ private:
|
||||
bool HadErrors);
|
||||
|
||||
// configuration
|
||||
const ThreadsafeFS &FSProvider;
|
||||
const ThreadsafeFS &TFS;
|
||||
const GlobalCompilationDatabase &CDB;
|
||||
Context BackgroundContext;
|
||||
|
||||
|
@ -676,7 +676,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
|
||||
CCOpts.AllScopes = AllScopesCompletion;
|
||||
CCOpts.RunParser = CodeCompletionParse;
|
||||
|
||||
RealThreadsafeFS FSProvider;
|
||||
RealThreadsafeFS TFS;
|
||||
// Initialize and run ClangdLSPServer.
|
||||
// Change stdin to binary to not lose \r\n on windows.
|
||||
llvm::sys::ChangeStdinToBinary();
|
||||
@ -719,8 +719,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
|
||||
ClangTidyOptProvider = std::make_unique<tidy::FileOptionsProvider>(
|
||||
tidy::ClangTidyGlobalOptions(),
|
||||
/* Default */ EmptyDefaults,
|
||||
/* Override */ OverrideClangTidyOptions,
|
||||
FSProvider.view(/*CWD=*/llvm::None));
|
||||
/* Override */ OverrideClangTidyOptions, TFS.view(/*CWD=*/llvm::None));
|
||||
Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &,
|
||||
llvm::StringRef File) {
|
||||
// This function must be thread-safe and tidy option providers are not.
|
||||
@ -771,7 +770,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
|
||||
Opts.AsyncPreambleBuilds = AsyncPreamble;
|
||||
|
||||
ClangdLSPServer LSPServer(
|
||||
*TransportLayer, FSProvider, CCOpts, RenameOpts, CompileCommandsDirPath,
|
||||
*TransportLayer, TFS, CCOpts, RenameOpts, CompileCommandsDirPath,
|
||||
/*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs,
|
||||
OffsetEncodingFromFlag, Opts);
|
||||
llvm::set_thread_name("clangd.main");
|
||||
|
@ -272,7 +272,7 @@ int b = a;
|
||||
|
||||
TEST_F(ClangdVFSTest, PropagatesContexts) {
|
||||
static Key<int> Secret;
|
||||
struct FSProvider : public ThreadsafeFS {
|
||||
struct ContextReadingFS : public ThreadsafeFS {
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem>
|
||||
view(llvm::NoneType) const override {
|
||||
Got = Context::current().getExisting(Secret);
|
||||
@ -924,17 +924,17 @@ TEST_F(ClangdVFSTest, ChangedHeaderFromISystem) {
|
||||
// Check that running code completion doesn't stat() a bunch of files from the
|
||||
// preamble again. (They should be using the preamble's stat-cache)
|
||||
TEST(ClangdTests, PreambleVFSStatCache) {
|
||||
class ListenStatsFSProvider : public ThreadsafeFS {
|
||||
class StatRecordingFS : public ThreadsafeFS {
|
||||
public:
|
||||
ListenStatsFSProvider(llvm::StringMap<unsigned> &CountStats)
|
||||
StatRecordingFS(llvm::StringMap<unsigned> &CountStats)
|
||||
: CountStats(CountStats) {}
|
||||
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem>
|
||||
view(llvm::NoneType) const override {
|
||||
class ListenStatVFS : public llvm::vfs::ProxyFileSystem {
|
||||
class StatRecordingVFS : public llvm::vfs::ProxyFileSystem {
|
||||
public:
|
||||
ListenStatVFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
|
||||
llvm::StringMap<unsigned> &CountStats)
|
||||
StatRecordingVFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
|
||||
llvm::StringMap<unsigned> &CountStats)
|
||||
: ProxyFileSystem(std::move(FS)), CountStats(CountStats) {}
|
||||
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
|
||||
@ -951,8 +951,8 @@ TEST(ClangdTests, PreambleVFSStatCache) {
|
||||
llvm::StringMap<unsigned> &CountStats;
|
||||
};
|
||||
|
||||
return IntrusiveRefCntPtr<ListenStatVFS>(
|
||||
new ListenStatVFS(buildTestFS(Files), CountStats));
|
||||
return IntrusiveRefCntPtr<StatRecordingVFS>(
|
||||
new StatRecordingVFS(buildTestFS(Files), CountStats));
|
||||
}
|
||||
|
||||
// If relative paths are used, they are resolved with testPath().
|
||||
@ -961,7 +961,7 @@ TEST(ClangdTests, PreambleVFSStatCache) {
|
||||
};
|
||||
|
||||
llvm::StringMap<unsigned> CountStats;
|
||||
ListenStatsFSProvider FS(CountStats);
|
||||
StatRecordingFS FS(CountStats);
|
||||
ErrorCheckingCallbacks DiagConsumer;
|
||||
MockCompilationDatabase CDB;
|
||||
ClangdServer Server(CDB, FS, ClangdServer::optsForTest(), &DiagConsumer);
|
||||
|
@ -272,14 +272,14 @@ TEST(FileIndexTest, RebuildWithPreamble) {
|
||||
PI.CompileCommand.Filename = FooCpp;
|
||||
PI.CompileCommand.CommandLine = {"clang", "-xc++", FooCpp};
|
||||
|
||||
MockFS FSProvider;
|
||||
FSProvider.Files[FooCpp] = "";
|
||||
FSProvider.Files[FooH] = R"cpp(
|
||||
MockFS FS;
|
||||
FS.Files[FooCpp] = "";
|
||||
FS.Files[FooH] = R"cpp(
|
||||
namespace ns_in_header {
|
||||
int func_in_header();
|
||||
}
|
||||
)cpp";
|
||||
PI.FSProvider = &FSProvider;
|
||||
PI.TFS = &FS;
|
||||
|
||||
PI.Contents = R"cpp(
|
||||
#include "foo.h"
|
||||
|
@ -51,14 +51,14 @@ ClangdServer::Options optsForTests() {
|
||||
|
||||
class WorkspaceSymbolsTest : public ::testing::Test {
|
||||
public:
|
||||
WorkspaceSymbolsTest() : Server(CDB, FSProvider, optsForTests()) {
|
||||
WorkspaceSymbolsTest() : Server(CDB, FS, optsForTests()) {
|
||||
// Make sure the test root directory is created.
|
||||
FSProvider.Files[testPath("unused")] = "";
|
||||
FS.Files[testPath("unused")] = "";
|
||||
CDB.ExtraClangFlags = {"-xc++"};
|
||||
}
|
||||
|
||||
protected:
|
||||
MockFS FSProvider;
|
||||
MockFS FS;
|
||||
MockCompilationDatabase CDB;
|
||||
ClangdServer Server;
|
||||
int Limit = 0;
|
||||
@ -307,10 +307,10 @@ TEST_F(WorkspaceSymbolsTest, TempSpecs) {
|
||||
namespace {
|
||||
class DocumentSymbolsTest : public ::testing::Test {
|
||||
public:
|
||||
DocumentSymbolsTest() : Server(CDB, FSProvider, optsForTests()) {}
|
||||
DocumentSymbolsTest() : Server(CDB, FS, optsForTests()) {}
|
||||
|
||||
protected:
|
||||
MockFS FSProvider;
|
||||
MockFS FS;
|
||||
MockCompilationDatabase CDB;
|
||||
ClangdServer Server;
|
||||
|
||||
|
@ -48,12 +48,12 @@ private:
|
||||
|
||||
ParseInputs PI;
|
||||
PI.CompileCommand = *Cmd;
|
||||
PI.FSProvider = &FS;
|
||||
PI.TFS = &FS;
|
||||
auto CI = buildCompilerInvocation(PI, IgnoreDiags);
|
||||
EXPECT_TRUE(static_cast<bool>(CI));
|
||||
// The diagnostic options must be set before creating a CompilerInstance.
|
||||
CI->getDiagnosticOpts().IgnoreWarnings = true;
|
||||
auto VFS = PI.FSProvider->view(Cmd->Directory);
|
||||
auto VFS = PI.TFS->view(Cmd->Directory);
|
||||
auto Clang = prepareCompilerInstance(
|
||||
std::move(CI), /*Preamble=*/nullptr,
|
||||
llvm::MemoryBuffer::getMemBuffer(FS.Files[MainFile], MainFile),
|
||||
|
@ -249,11 +249,11 @@ TEST(ParsedASTTest, NoCrashOnTokensWithTidyCheck) {
|
||||
}
|
||||
|
||||
TEST(ParsedASTTest, CanBuildInvocationWithUnknownArgs) {
|
||||
MockFS FSProvider;
|
||||
FSProvider.Files = {{testPath("foo.cpp"), "void test() {}"}};
|
||||
MockFS FS;
|
||||
FS.Files = {{testPath("foo.cpp"), "void test() {}"}};
|
||||
// Unknown flags should not prevent a build of compiler invocation.
|
||||
ParseInputs Inputs;
|
||||
Inputs.FSProvider = &FSProvider;
|
||||
Inputs.TFS = &FS;
|
||||
Inputs.CompileCommand.CommandLine = {"clang", "-fsome-unknown-flag",
|
||||
testPath("foo.cpp")};
|
||||
IgnoreDiagnostics IgnoreDiags;
|
||||
|
@ -70,11 +70,11 @@ collectPatchedIncludes(llvm::StringRef ModifiedContents,
|
||||
// We don't run PP directly over the patch cotents to test production
|
||||
// behaviour.
|
||||
auto Bounds = Lexer::ComputePreamble(ModifiedContents, *CI->getLangOpts());
|
||||
auto Clang = prepareCompilerInstance(
|
||||
std::move(CI), &BaselinePreamble->Preamble,
|
||||
llvm::MemoryBuffer::getMemBufferCopy(
|
||||
ModifiedContents.slice(0, Bounds.Size).str()),
|
||||
PI.FSProvider->view(PI.CompileCommand.Directory), Diags);
|
||||
auto Clang =
|
||||
prepareCompilerInstance(std::move(CI), &BaselinePreamble->Preamble,
|
||||
llvm::MemoryBuffer::getMemBufferCopy(
|
||||
ModifiedContents.slice(0, Bounds.Size).str()),
|
||||
PI.TFS->view(PI.CompileCommand.Directory), Diags);
|
||||
PreprocessOnlyAction Action;
|
||||
if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
|
||||
ADD_FAILURE() << "failed begin source file";
|
||||
@ -518,12 +518,12 @@ TEST(PreamblePatch, ModifiedBounds) {
|
||||
|
||||
Annotations Modified(Case.Modified);
|
||||
TU.Code = Modified.code().str();
|
||||
MockFS FSProvider;
|
||||
auto PP = PreamblePatch::create(testPath(TU.Filename),
|
||||
TU.inputs(FSProvider), *BaselinePreamble);
|
||||
MockFS FS;
|
||||
auto PP = PreamblePatch::create(testPath(TU.Filename), TU.inputs(FS),
|
||||
*BaselinePreamble);
|
||||
|
||||
IgnoreDiagnostics Diags;
|
||||
auto CI = buildCompilerInvocation(TU.inputs(FSProvider), Diags);
|
||||
auto CI = buildCompilerInvocation(TU.inputs(FS), Diags);
|
||||
ASSERT_TRUE(CI);
|
||||
|
||||
const auto ExpectedBounds =
|
||||
|
@ -74,7 +74,7 @@ protected:
|
||||
ParseInputs getInputs(PathRef File, std::string Contents) {
|
||||
ParseInputs Inputs;
|
||||
Inputs.CompileCommand = *CDB.getCompileCommand(File);
|
||||
Inputs.FSProvider = &FSProvider;
|
||||
Inputs.TFS = &FS;
|
||||
Inputs.Contents = std::move(Contents);
|
||||
Inputs.Opts = ParseOptions();
|
||||
return Inputs;
|
||||
@ -150,7 +150,7 @@ protected:
|
||||
std::move(CB));
|
||||
}
|
||||
|
||||
MockFS FSProvider;
|
||||
MockFS FS;
|
||||
MockCompilationDatabase CDB;
|
||||
};
|
||||
|
||||
@ -161,10 +161,10 @@ TEST_F(TUSchedulerTests, MissingFiles) {
|
||||
TUScheduler S(CDB, optsForTest());
|
||||
|
||||
auto Added = testPath("added.cpp");
|
||||
FSProvider.Files[Added] = "x";
|
||||
FS.Files[Added] = "x";
|
||||
|
||||
auto Missing = testPath("missing.cpp");
|
||||
FSProvider.Files[Missing] = "";
|
||||
FS.Files[Missing] = "";
|
||||
|
||||
S.update(Added, getInputs(Added, "x"), WantDiagnostics::No);
|
||||
|
||||
@ -425,7 +425,7 @@ TEST_F(TUSchedulerTests, ManyUpdates) {
|
||||
for (int I = 0; I < FilesCount; ++I) {
|
||||
std::string Name = "foo" + std::to_string(I) + ".cpp";
|
||||
Files.push_back(testPath(Name));
|
||||
this->FSProvider.Files[Files.back()] = "";
|
||||
this->FS.Files[Files.back()] = "";
|
||||
}
|
||||
|
||||
StringRef Contents1 = R"cpp(int a;)cpp";
|
||||
@ -616,8 +616,8 @@ TEST_F(TUSchedulerTests, EmptyPreamble) {
|
||||
auto Foo = testPath("foo.cpp");
|
||||
auto Header = testPath("foo.h");
|
||||
|
||||
FSProvider.Files[Header] = "void foo()";
|
||||
FSProvider.Timestamps[Header] = time_t(0);
|
||||
FS.Files[Header] = "void foo()";
|
||||
FS.Timestamps[Header] = time_t(0);
|
||||
auto WithPreamble = R"cpp(
|
||||
#include "foo.h"
|
||||
int main() {}
|
||||
@ -685,8 +685,8 @@ TEST_F(TUSchedulerTests, NoopOnEmptyChanges) {
|
||||
auto Source = testPath("foo.cpp");
|
||||
auto Header = testPath("foo.h");
|
||||
|
||||
FSProvider.Files[Header] = "int a;";
|
||||
FSProvider.Timestamps[Header] = time_t(0);
|
||||
FS.Files[Header] = "int a;";
|
||||
FS.Timestamps[Header] = time_t(0);
|
||||
|
||||
std::string SourceContents = R"cpp(
|
||||
#include "foo.h"
|
||||
@ -714,7 +714,7 @@ TEST_F(TUSchedulerTests, NoopOnEmptyChanges) {
|
||||
ASSERT_EQ(S.fileStats().lookup(Source).PreambleBuilds, 1u);
|
||||
|
||||
// Update to a header should cause a rebuild, though.
|
||||
FSProvider.Timestamps[Header] = time_t(1);
|
||||
FS.Timestamps[Header] = time_t(1);
|
||||
ASSERT_TRUE(DoUpdate(SourceContents));
|
||||
ASSERT_FALSE(DoUpdate(SourceContents));
|
||||
ASSERT_EQ(S.fileStats().lookup(Source).ASTBuilds, 2u);
|
||||
@ -742,8 +742,8 @@ TEST_F(TUSchedulerTests, MissingHeader) {
|
||||
CDB.ExtraClangFlags.push_back("-I" + testPath("a"));
|
||||
CDB.ExtraClangFlags.push_back("-I" + testPath("b"));
|
||||
// Force both directories to exist so they don't get pruned.
|
||||
FSProvider.Files.try_emplace("a/__unused__");
|
||||
FSProvider.Files.try_emplace("b/__unused__");
|
||||
FS.Files.try_emplace("a/__unused__");
|
||||
FS.Files.try_emplace("b/__unused__");
|
||||
TUScheduler S(CDB, optsForTest(), captureDiags());
|
||||
|
||||
auto Source = testPath("foo.cpp");
|
||||
@ -771,8 +771,8 @@ TEST_F(TUSchedulerTests, MissingHeader) {
|
||||
});
|
||||
S.blockUntilIdle(timeoutSeconds(10));
|
||||
|
||||
FSProvider.Files[HeaderB] = "int b;";
|
||||
FSProvider.Timestamps[HeaderB] = time_t(1);
|
||||
FS.Files[HeaderB] = "int b;";
|
||||
FS.Timestamps[HeaderB] = time_t(1);
|
||||
|
||||
// The addition of the missing header file triggers a rebuild, no errors.
|
||||
updateWithDiags(S, Source, Inputs, WantDiagnostics::Yes,
|
||||
@ -784,8 +784,8 @@ TEST_F(TUSchedulerTests, MissingHeader) {
|
||||
// Ensure previous assertions are done before we touch the FS again.
|
||||
ASSERT_TRUE(S.blockUntilIdle(timeoutSeconds(10)));
|
||||
// Add the high-priority header file, which should reintroduce the error.
|
||||
FSProvider.Files[HeaderA] = "int a;";
|
||||
FSProvider.Timestamps[HeaderA] = time_t(1);
|
||||
FS.Files[HeaderA] = "int a;";
|
||||
FS.Timestamps[HeaderA] = time_t(1);
|
||||
|
||||
// This isn't detected: we don't stat a/foo.h to validate the preamble.
|
||||
updateWithDiags(S, Source, Inputs, WantDiagnostics::Yes,
|
||||
|
@ -20,7 +20,7 @@
|
||||
namespace clang {
|
||||
namespace clangd {
|
||||
|
||||
ParseInputs TestTU::inputs(MockFS &FSProvider) const {
|
||||
ParseInputs TestTU::inputs(MockFS &FS) const {
|
||||
std::string FullFilename = testPath(Filename),
|
||||
FullHeaderName = testPath(HeaderFilename),
|
||||
ImportThunk = testPath("import_thunk.h");
|
||||
@ -29,10 +29,10 @@ ParseInputs TestTU::inputs(MockFS &FSProvider) const {
|
||||
// guard without messing up offsets). In this case, use an intermediate file.
|
||||
std::string ThunkContents = "#import \"" + FullHeaderName + "\"\n";
|
||||
|
||||
FSProvider.Files = AdditionalFiles;
|
||||
FSProvider.Files[FullFilename] = Code;
|
||||
FSProvider.Files[FullHeaderName] = HeaderCode;
|
||||
FSProvider.Files[ImportThunk] = ThunkContents;
|
||||
FS.Files = AdditionalFiles;
|
||||
FS.Files[FullFilename] = Code;
|
||||
FS.Files[FullHeaderName] = HeaderCode;
|
||||
FS.Files[ImportThunk] = ThunkContents;
|
||||
|
||||
ParseInputs Inputs;
|
||||
auto &Argv = Inputs.CompileCommand.CommandLine;
|
||||
@ -54,7 +54,7 @@ ParseInputs TestTU::inputs(MockFS &FSProvider) const {
|
||||
Inputs.CompileCommand.Filename = FullFilename;
|
||||
Inputs.CompileCommand.Directory = testRoot();
|
||||
Inputs.Contents = Code;
|
||||
Inputs.FSProvider = &FSProvider;
|
||||
Inputs.TFS = &FS;
|
||||
Inputs.Opts = ParseOptions();
|
||||
Inputs.Opts.BuildRecoveryAST = true;
|
||||
Inputs.Opts.PreserveRecoveryASTType = true;
|
||||
@ -67,8 +67,8 @@ ParseInputs TestTU::inputs(MockFS &FSProvider) const {
|
||||
}
|
||||
|
||||
std::shared_ptr<const PreambleData> TestTU::preamble() const {
|
||||
MockFS FSProvider;
|
||||
auto Inputs = inputs(FSProvider);
|
||||
MockFS FS;
|
||||
auto Inputs = inputs(FS);
|
||||
IgnoreDiagnostics Diags;
|
||||
auto CI = buildCompilerInvocation(Inputs, Diags);
|
||||
assert(CI && "Failed to build compilation invocation.");
|
||||
@ -78,8 +78,8 @@ std::shared_ptr<const PreambleData> TestTU::preamble() const {
|
||||
}
|
||||
|
||||
ParsedAST TestTU::build() const {
|
||||
MockFS FSProvider;
|
||||
auto Inputs = inputs(FSProvider);
|
||||
MockFS FS;
|
||||
auto Inputs = inputs(FS);
|
||||
StoreDiags Diags;
|
||||
auto CI = buildCompilerInvocation(Inputs, Diags);
|
||||
assert(CI && "Failed to build compilation invocation.");
|
||||
|
@ -70,7 +70,7 @@ struct TestTU {
|
||||
// Suppress this behavior by adding an 'error-ok' comment to the code.
|
||||
ParsedAST build() const;
|
||||
std::shared_ptr<const PreambleData> preamble() const;
|
||||
ParseInputs inputs(MockFS &FSProvider) const;
|
||||
ParseInputs inputs(MockFS &FS) const;
|
||||
SymbolSlab headerSymbols() const;
|
||||
RefSlab headerRefs() const;
|
||||
std::unique_ptr<SymbolIndex> index() const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user