diff options
Diffstat (limited to 'clang-tools-extra/clangd')
-rw-r--r-- | clang-tools-extra/clangd/ClangdLSPServer.cpp | 11 | ||||
-rw-r--r-- | clang-tools-extra/clangd/ClangdLSPServer.h | 8 | ||||
-rw-r--r-- | clang-tools-extra/clangd/ClangdServer.cpp | 34 | ||||
-rw-r--r-- | clang-tools-extra/clangd/ClangdServer.h | 70 | ||||
-rw-r--r-- | clang-tools-extra/clangd/tool/ClangdMain.cpp | 33 |
5 files changed, 74 insertions, 82 deletions
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 6e232050ff7..539ee17acf4 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -395,17 +395,12 @@ void ClangdLSPServer::onChangeConfiguration( } } -ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, - bool StorePreamblesInMemory, +ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, const clangd::CodeCompleteOptions &CCOpts, - llvm::Optional<StringRef> ResourceDir, llvm::Optional<Path> CompileCommandsDir, - bool BuildDynamicSymbolIndex, - SymbolIndex *StaticIdx) + const ClangdServer::Options &Opts) : Out(Out), CDB(std::move(CompileCommandsDir)), CCOpts(CCOpts), - Server(CDB, /*DiagConsumer=*/*this, FSProvider, AsyncThreadsCount, - StorePreamblesInMemory, BuildDynamicSymbolIndex, StaticIdx, - ResourceDir, /*UpdateDebounce=*/std::chrono::milliseconds(500)) {} + Server(CDB, FSProvider, /*DiagConsumer=*/*this, Opts) {} bool ClangdLSPServer::run(std::istream &In, JSONStreamStyle InputStyle) { assert(!IsDone && "Run was called before"); diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index c3c0f80744c..30e174611b7 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -31,13 +31,9 @@ public: /// If \p CompileCommandsDir has a value, compile_commands.json will be /// loaded only from \p CompileCommandsDir. Otherwise, clangd will look /// for compile_commands.json in all parent directories of each file. - ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, - bool StorePreamblesInMemory, - const clangd::CodeCompleteOptions &CCOpts, - llvm::Optional<StringRef> ResourceDir, + ClangdLSPServer(JSONOutput &Out, const clangd::CodeCompleteOptions &CCOpts, llvm::Optional<Path> CompileCommandsDir, - bool BuildDynamicSymbolIndex, - SymbolIndex *StaticIdx = nullptr); + const ClangdServer::Options &Opts); /// Run LSP server loop, receiving input for it from \p In. \p In must be /// opened in binary mode. Output will be written using Out variable passed to diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 88b0664d737..db65d5c351f 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -70,37 +70,41 @@ RealFileSystemProvider::getTaggedFileSystem(PathRef File) { return make_tagged(vfs::getRealFileSystem(), VFSTag()); } +ClangdServer::Options ClangdServer::optsForTest() { + ClangdServer::Options Opts; + Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster! + Opts.StorePreamblesInMemory = true; + Opts.AsyncThreadsCount = 4; // Consistent! + return Opts; +} + ClangdServer::ClangdServer(GlobalCompilationDatabase &CDB, - DiagnosticsConsumer &DiagConsumer, FileSystemProvider &FSProvider, - unsigned AsyncThreadsCount, - bool StorePreamblesInMemory, - bool BuildDynamicSymbolIndex, SymbolIndex *StaticIdx, - llvm::Optional<StringRef> ResourceDir, - std::chrono::steady_clock::duration UpdateDebounce) - : CompileArgs(CDB, - ResourceDir ? ResourceDir->str() : getStandardResourceDir()), + DiagnosticsConsumer &DiagConsumer, + const Options &Opts) + : CompileArgs(CDB, Opts.ResourceDir ? Opts.ResourceDir->str() + : getStandardResourceDir()), DiagConsumer(DiagConsumer), FSProvider(FSProvider), - FileIdx(BuildDynamicSymbolIndex ? new FileIndex() : nullptr), + FileIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex() : nullptr), PCHs(std::make_shared<PCHContainerOperations>()), // Pass a callback into `WorkScheduler` to extract symbols from a newly // parsed file and rebuild the file index synchronously each time an AST // is parsed. // FIXME(ioeric): this can be slow and we may be able to index on less // critical paths. - WorkScheduler(AsyncThreadsCount, StorePreamblesInMemory, + WorkScheduler(Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory, FileIdx ? [this](PathRef Path, ParsedAST *AST) { FileIdx->update(Path, AST); } : ASTParsedCallback(), - UpdateDebounce) { - if (FileIdx && StaticIdx) { - MergedIndex = mergeIndex(FileIdx.get(), StaticIdx); + Opts.UpdateDebounce) { + if (FileIdx && Opts.StaticIndex) { + MergedIndex = mergeIndex(FileIdx.get(), Opts.StaticIndex); Index = MergedIndex.get(); } else if (FileIdx) Index = FileIdx.get(); - else if (StaticIdx) - Index = StaticIdx; + else if (Opts.StaticIndex) + Index = Opts.StaticIndex; else Index = nullptr; } diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index a443d66229a..5e10c243ed1 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -101,19 +101,36 @@ public: /// definition. class ClangdServer { public: + struct Options { + /// To process requests asynchronously, ClangdServer spawns worker threads. + /// If 0, all requests are processed on the calling thread. + unsigned AsyncThreadsCount = getDefaultAsyncThreadsCount(); + + /// Cached preambles are potentially large. If false, store them on disk. + bool StorePreamblesInMemory = true; + + /// If true, ClangdServer builds a dynamic in-memory index for symbols in + /// opened files and uses the index to augment code completion results. + bool BuildDynamicSymbolIndex = false; + + /// If set, use this index to augment code completion results. + SymbolIndex *StaticIndex = nullptr; + + /// The resource directory is used to find internal headers, overriding + /// defaults and -resource-dir compiler flag). + /// If None, ClangdServer calls CompilerInvocation::GetResourcePath() to + /// obtain the standard resource directory. + llvm::Optional<StringRef> ResourceDir = llvm::None; + + /// Time to wait after a new file version before computing diagnostics. + std::chrono::steady_clock::duration UpdateDebounce = + std::chrono::milliseconds(500); + }; + // Sensible default options for use in tests. + // Features like indexing must be enabled if desired. + static Options optsForTest(); + /// Creates a new ClangdServer instance. - /// To process parsing requests asynchronously, ClangdServer will spawn \p - /// AsyncThreadsCount worker threads. However, if \p AsyncThreadsCount is 0, - /// all requests will be processed on the calling thread. - /// - /// ClangdServer uses \p FSProvider to get an instance of vfs::FileSystem for - /// each parsing request. Results of code completion and diagnostics also - /// include a tag, that \p FSProvider returns along with the vfs::FileSystem. - /// - /// The value of \p ResourceDir will be used to search for internal headers - /// (overriding defaults and -resource-dir compiler flag). If \p ResourceDir - /// is None, ClangdServer will call CompilerInvocation::GetResourcePath() to - /// obtain the standard resource directory. /// /// ClangdServer uses \p CDB to obtain compilation arguments for parsing. Note /// that ClangdServer only obtains compilation arguments once for each newly @@ -121,33 +138,16 @@ public: /// those arguments for subsequent reparses. However, ClangdServer will check /// if compilation arguments changed on calls to forceReparse(). /// + /// FSProvider provides a vfs::FileSystem for each parsing request. Results of + /// code completion and diagnostics also include a tag, that \p FSProvider + /// returns along with the vfs::FileSystem. + /// /// After each parsing request finishes, ClangdServer reports diagnostics to /// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a /// worker thread. Therefore, instances of \p DiagConsumer must properly /// synchronize access to shared state. - /// UpdateDebounce determines how long to wait after a new version of the file - /// before starting to compute diagnostics. - /// - /// \p StorePreamblesInMemory defines whether the Preambles generated by - /// clangd are stored in-memory or on disk. - /// - /// If \p BuildDynamicSymbolIndex is true, ClangdServer builds a dynamic - /// in-memory index for symbols in all opened files and uses the index to - /// augment code completion results. - /// - /// If \p StaticIdx is set, ClangdServer uses the index for global code - /// completion. - /// FIXME(sammccall): pull out an options struct. - ClangdServer(GlobalCompilationDatabase &CDB, - DiagnosticsConsumer &DiagConsumer, - FileSystemProvider &FSProvider, unsigned AsyncThreadsCount, - bool StorePreamblesInMemory, - bool BuildDynamicSymbolIndex = false, - SymbolIndex *StaticIdx = nullptr, - llvm::Optional<StringRef> ResourceDir = llvm::None, - /* Tiny default debounce, so tests hit the debounce logic */ - std::chrono::steady_clock::duration UpdateDebounce = - std::chrono::milliseconds(20)); + ClangdServer(GlobalCompilationDatabase &CDB, FileSystemProvider &FSProvider, + DiagnosticsConsumer &DiagConsumer, const Options &Opts); /// Set the root path of the workspace. void setRootPath(PathRef RootPath); diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 00d18185275..4d579b46399 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -188,9 +188,7 @@ int main(int argc, char *argv[]) { if (Tracer) TracingSession.emplace(*Tracer); - llvm::raw_ostream &Outs = llvm::outs(); - llvm::raw_ostream &Logs = llvm::errs(); - JSONOutput Out(Outs, Logs, + JSONOutput Out(llvm::outs(), llvm::errs(), InputMirrorStream ? InputMirrorStream.getPointer() : nullptr, PrettyPrint); @@ -199,7 +197,6 @@ int main(int argc, char *argv[]) { // If --compile-commands-dir arg was invoked, check value and override default // path. llvm::Optional<Path> CompileCommandsDirPath; - if (CompileCommandsDir.empty()) { CompileCommandsDirPath = llvm::None; } else if (!llvm::sys::path::is_absolute(CompileCommandsDir) || @@ -212,34 +209,34 @@ int main(int argc, char *argv[]) { CompileCommandsDirPath = CompileCommandsDir; } - bool StorePreamblesInMemory; + ClangdServer::Options Opts; switch (PCHStorage) { case PCHStorageFlag::Memory: - StorePreamblesInMemory = true; + Opts.StorePreamblesInMemory = true; break; case PCHStorageFlag::Disk: - StorePreamblesInMemory = false; + Opts.StorePreamblesInMemory = false; break; } - - llvm::Optional<StringRef> ResourceDirRef = None; if (!ResourceDir.empty()) - ResourceDirRef = ResourceDir; - - // Change stdin to binary to not lose \r\n on windows. - llvm::sys::ChangeStdinToBinary(); - + Opts.ResourceDir = ResourceDir; + Opts.BuildDynamicSymbolIndex = EnableIndexBasedCompletion; std::unique_ptr<SymbolIndex> StaticIdx; - if (EnableIndexBasedCompletion && !YamlSymbolFile.empty()) + if (EnableIndexBasedCompletion && !YamlSymbolFile.empty()) { StaticIdx = BuildStaticIndex(YamlSymbolFile); + Opts.StaticIndex = StaticIdx.get(); + } + Opts.AsyncThreadsCount = WorkerThreadsCount; + clangd::CodeCompleteOptions CCOpts; CCOpts.IncludeIneligibleResults = IncludeIneligibleResults; CCOpts.Limit = LimitCompletionResult; + // Initialize and run ClangdLSPServer. - ClangdLSPServer LSPServer(Out, WorkerThreadsCount, StorePreamblesInMemory, - CCOpts, ResourceDirRef, CompileCommandsDirPath, - EnableIndexBasedCompletion, StaticIdx.get()); + ClangdLSPServer LSPServer(Out, CCOpts, CompileCommandsDirPath, Opts); constexpr int NoShutdownRequestErrorCode = 1; llvm::set_thread_name("clangd.main"); + // Change stdin to binary to not lose \r\n on windows. + llvm::sys::ChangeStdinToBinary(); return LSPServer.run(std::cin, InputStyle) ? 0 : NoShutdownRequestErrorCode; } |