LCOV - code coverage report
Current view: top level - clang/tools/extra/clangd - ClangdServer.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 0 2 0.0 %
Date: 2018-07-13 00:08:38 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- ClangdServer.h - Main clangd server code ----------------*- 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             : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
      11             : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H
      12             : 
      13             : #include "ClangdUnit.h"
      14             : #include "CodeComplete.h"
      15             : #include "Function.h"
      16             : #include "GlobalCompilationDatabase.h"
      17             : #include "Protocol.h"
      18             : #include "TUScheduler.h"
      19             : #include "index/FileIndex.h"
      20             : #include "clang/Tooling/CompilationDatabase.h"
      21             : #include "clang/Tooling/Core/Replacement.h"
      22             : #include "llvm/ADT/IntrusiveRefCntPtr.h"
      23             : #include "llvm/ADT/Optional.h"
      24             : #include "llvm/ADT/StringRef.h"
      25             : #include <functional>
      26             : #include <future>
      27             : #include <string>
      28             : #include <type_traits>
      29             : #include <utility>
      30             : 
      31             : namespace clang {
      32             : class PCHContainerOperations;
      33             : 
      34             : namespace clangd {
      35             : 
      36             : class DiagnosticsConsumer {
      37             : public:
      38             :   virtual ~DiagnosticsConsumer() = default;
      39             : 
      40             :   /// Called by ClangdServer when \p Diagnostics for \p File are ready.
      41             :   virtual void onDiagnosticsReady(PathRef File,
      42             :                                   std::vector<Diag> Diagnostics) = 0;
      43             : };
      44             : 
      45             : class FileSystemProvider {
      46             : public:
      47             :   virtual ~FileSystemProvider() = default;
      48             :   /// Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing.
      49             :   /// Context::current() will be the context passed to the clang entrypoint,
      50             :   /// such as addDocument(), and will also be propagated to result callbacks.
      51             :   /// Embedders may use this to isolate filesystem accesses.
      52             :   virtual IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() = 0;
      53             : };
      54             : 
      55             : class RealFileSystemProvider : public FileSystemProvider {
      56             : public:
      57             :   /// Returns getRealFileSystem().
      58             :   IntrusiveRefCntPtr<vfs::FileSystem> getFileSystem() override;
      59             : };
      60             : 
      61             : /// Provides API to manage ASTs for a collection of C++ files and request
      62             : /// various language features.
      63             : /// Currently supports async diagnostics, code completion, formatting and goto
      64             : /// definition.
      65           0 : class ClangdServer {
      66             : public:
      67           0 :   struct Options {
      68             :     /// To process requests asynchronously, ClangdServer spawns worker threads.
      69             :     /// If 0, all requests are processed on the calling thread.
      70             :     unsigned AsyncThreadsCount = getDefaultAsyncThreadsCount();
      71             : 
      72             :     /// AST caching policy. The default is to keep up to 3 ASTs in memory.
      73             :     ASTRetentionPolicy RetentionPolicy;
      74             : 
      75             :     /// Cached preambles are potentially large. If false, store them on disk.
      76             :     bool StorePreamblesInMemory = true;
      77             : 
      78             :     /// If true, ClangdServer builds a dynamic in-memory index for symbols in
      79             :     /// opened files and uses the index to augment code completion results.
      80             :     bool BuildDynamicSymbolIndex = false;
      81             : 
      82             :     /// URI schemes to use when building the dynamic index.
      83             :     /// If empty, the default schemes in SymbolCollector will be used.
      84             :     std::vector<std::string> URISchemes;
      85             : 
      86             :     /// If set, use this index to augment code completion results.
      87             :     SymbolIndex *StaticIndex = nullptr;
      88             : 
      89             :     /// The resource directory is used to find internal headers, overriding
      90             :     /// defaults and -resource-dir compiler flag).
      91             :     /// If None, ClangdServer calls CompilerInvocation::GetResourcePath() to
      92             :     /// obtain the standard resource directory.
      93             :     llvm::Optional<StringRef> ResourceDir = llvm::None;
      94             : 
      95             :     /// Time to wait after a new file version before computing diagnostics.
      96             :     std::chrono::steady_clock::duration UpdateDebounce =
      97             :         std::chrono::milliseconds(500);
      98             :   };
      99             :   // Sensible default options for use in tests.
     100             :   // Features like indexing must be enabled if desired.
     101             :   static Options optsForTest();
     102             : 
     103             :   /// Creates a new ClangdServer instance.
     104             :   ///
     105             :   /// ClangdServer uses \p CDB to obtain compilation arguments for parsing. Note
     106             :   /// that ClangdServer only obtains compilation arguments once for each newly
     107             :   /// added file (i.e., when processing a first call to addDocument) and reuses
     108             :   /// those arguments for subsequent reparses. However, ClangdServer will check
     109             :   /// if compilation arguments changed on calls to forceReparse().
     110             :   ///
     111             :   /// After each parsing request finishes, ClangdServer reports diagnostics to
     112             :   /// \p DiagConsumer. Note that a callback to \p DiagConsumer happens on a
     113             :   /// worker thread. Therefore, instances of \p DiagConsumer must properly
     114             :   /// synchronize access to shared state.
     115             :   ClangdServer(GlobalCompilationDatabase &CDB, FileSystemProvider &FSProvider,
     116             :                DiagnosticsConsumer &DiagConsumer, const Options &Opts);
     117             : 
     118             :   /// Set the root path of the workspace.
     119             :   void setRootPath(PathRef RootPath);
     120             : 
     121             :   /// Add a \p File to the list of tracked C++ files or update the contents if
     122             :   /// \p File is already tracked. Also schedules parsing of the AST for it on a
     123             :   /// separate thread. When the parsing is complete, DiagConsumer passed in
     124             :   /// constructor will receive onDiagnosticsReady callback.
     125             :   /// When \p SkipCache is true, compile commands will always be requested from
     126             :   /// compilation database even if they were cached in previous invocations.
     127             :   void addDocument(PathRef File, StringRef Contents,
     128             :                    WantDiagnostics WD = WantDiagnostics::Auto);
     129             : 
     130             :   /// Remove \p File from list of tracked files, schedule a request to free
     131             :   /// resources associated with it.
     132             :   void removeDocument(PathRef File);
     133             : 
     134             :   /// Run code completion for \p File at \p Pos.
     135             :   /// Request is processed asynchronously.
     136             :   ///
     137             :   /// This method should only be called for currently tracked files. However, it
     138             :   /// is safe to call removeDocument for \p File after this method returns, even
     139             :   /// while returned future is not yet ready.
     140             :   /// A version of `codeComplete` that runs \p Callback on the processing thread
     141             :   /// when codeComplete results become available.
     142             :   void codeComplete(PathRef File, Position Pos,
     143             :                     const clangd::CodeCompleteOptions &Opts,
     144             :                     Callback<CodeCompleteResult> CB);
     145             : 
     146             :   /// Provide signature help for \p File at \p Pos.  This method should only be
     147             :   /// called for tracked files.
     148             :   void signatureHelp(PathRef File, Position Pos, Callback<SignatureHelp> CB);
     149             : 
     150             :   /// Get definition of symbol at a specified \p Line and \p Column in \p File.
     151             :   void findDefinitions(PathRef File, Position Pos,
     152             :                        Callback<std::vector<Location>> CB);
     153             : 
     154             :   /// Helper function that returns a path to the corresponding source file when
     155             :   /// given a header file and vice versa.
     156             :   llvm::Optional<Path> switchSourceHeader(PathRef Path);
     157             : 
     158             :   /// Get document highlights for a given position.
     159             :   void findDocumentHighlights(PathRef File, Position Pos,
     160             :                               Callback<std::vector<DocumentHighlight>> CB);
     161             : 
     162             :   /// Get code hover for a given position.
     163             :   void findHover(PathRef File, Position Pos,
     164             :                  Callback<llvm::Optional<Hover>> CB);
     165             : 
     166             :   /// Retrieve the top symbols from the workspace matching a query.
     167             :   void workspaceSymbols(StringRef Query, int Limit,
     168             :                         Callback<std::vector<SymbolInformation>> CB);
     169             : 
     170             :   /// Retrieve the symbols within the specified file.
     171             :   void documentSymbols(StringRef File,
     172             :                        Callback<std::vector<SymbolInformation>> CB);
     173             : 
     174             :   /// Run formatting for \p Rng inside \p File with content \p Code.
     175             :   llvm::Expected<tooling::Replacements> formatRange(StringRef Code,
     176             :                                                     PathRef File, Range Rng);
     177             : 
     178             :   /// Run formatting for the whole \p File with content \p Code.
     179             :   llvm::Expected<tooling::Replacements> formatFile(StringRef Code,
     180             :                                                    PathRef File);
     181             : 
     182             :   /// Run formatting after a character was typed at \p Pos in \p File with
     183             :   /// content \p Code.
     184             :   llvm::Expected<tooling::Replacements>
     185             :   formatOnType(StringRef Code, PathRef File, Position Pos);
     186             : 
     187             :   /// Rename all occurrences of the symbol at the \p Pos in \p File to
     188             :   /// \p NewName.
     189             :   void rename(PathRef File, Position Pos, llvm::StringRef NewName,
     190             :               Callback<std::vector<tooling::Replacement>> CB);
     191             : 
     192             :   /// Only for testing purposes.
     193             :   /// Waits until all requests to worker thread are finished and dumps AST for
     194             :   /// \p File. \p File must be in the list of added documents.
     195             :   void dumpAST(PathRef File, llvm::unique_function<void(std::string)> Callback);
     196             :   /// Called when an event occurs for a watched file in the workspace.
     197             :   void onFileEvent(const DidChangeWatchedFilesParams &Params);
     198             : 
     199             :   /// Returns estimated memory usage for each of the currently open files.
     200             :   /// The order of results is unspecified.
     201             :   /// Overall memory usage of clangd may be significantly more than reported
     202             :   /// here, as this metric does not account (at least) for:
     203             :   ///   - memory occupied by static and dynamic index,
     204             :   ///   - memory required for in-flight requests,
     205             :   /// FIXME: those metrics might be useful too, we should add them.
     206             :   std::vector<std::pair<Path, std::size_t>> getUsedBytesPerFile() const;
     207             : 
     208             :   // Blocks the main thread until the server is idle. Only for use in tests.
     209             :   // Returns false if the timeout expires.
     210             :   LLVM_NODISCARD bool
     211             :   blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
     212             : 
     213             : private:
     214             :   /// FIXME: This stats several files to find a .clang-format file. I/O can be
     215             :   /// slow. Think of a way to cache this.
     216             :   llvm::Expected<tooling::Replacements>
     217             :   formatCode(llvm::StringRef Code, PathRef File,
     218             :              ArrayRef<tooling::Range> Ranges);
     219             : 
     220             :   typedef uint64_t DocVersion;
     221             : 
     222             :   void consumeDiagnostics(PathRef File, DocVersion Version,
     223             :                           std::vector<Diag> Diags);
     224             : 
     225             :   tooling::CompileCommand getCompileCommand(PathRef File);
     226             : 
     227             :   GlobalCompilationDatabase &CDB;
     228             :   DiagnosticsConsumer &DiagConsumer;
     229             :   FileSystemProvider &FSProvider;
     230             : 
     231             :   /// Used to synchronize diagnostic responses for added and removed files.
     232             :   llvm::StringMap<DocVersion> InternalVersion;
     233             : 
     234             :   Path ResourceDir;
     235             :   // The index used to look up symbols. This could be:
     236             :   //   - null (all index functionality is optional)
     237             :   //   - the dynamic index owned by ClangdServer (FileIdx)
     238             :   //   - the static index passed to the constructor
     239             :   //   - a merged view of a static and dynamic index (MergedIndex)
     240             :   SymbolIndex *Index;
     241             :   // If present, an up-to-date of symbols in open files. Read via Index.
     242             :   std::unique_ptr<FileIndex> FileIdx;
     243             :   // If present, a merged view of FileIdx and an external index. Read via Index.
     244             :   std::unique_ptr<SymbolIndex> MergedIndex;
     245             :   // If set, this represents the workspace path.
     246             :   llvm::Optional<std::string> RootPath;
     247             :   std::shared_ptr<PCHContainerOperations> PCHs;
     248             :   /// Used to serialize diagnostic callbacks.
     249             :   /// FIXME(ibiryukov): get rid of an extra map and put all version counters
     250             :   /// into CppFile.
     251             :   std::mutex DiagnosticsMutex;
     252             :   /// Maps from a filename to the latest version of reported diagnostics.
     253             :   llvm::StringMap<DocVersion> ReportedDiagnosticVersions;
     254             :   // WorkScheduler has to be the last member, because its destructor has to be
     255             :   // called before all other members to stop the worker thread that references
     256             :   // ClangdServer.
     257             :   TUScheduler WorkScheduler;
     258             : };
     259             : 
     260             : } // namespace clangd
     261             : } // namespace clang
     262             : 
     263             : #endif

Generated by: LCOV version 1.13