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

Generated by: LCOV version 1.13