summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/ClangdLSPServer.h
blob: e3b67709ef5e0d38d2e10b2674781518b28861fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDLSPSERVER_H

#include "ClangdServer.h"
#include "DraftStore.h"
#include "FindSymbols.h"
#include "GlobalCompilationDatabase.h"
#include "Path.h"
#include "Protocol.h"
#include "ProtocolHandlers.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/Optional.h"

namespace clang {
namespace clangd {

class JSONOutput;
class SymbolIndex;

/// This class provides implementation of an LSP server, glueing the JSON
/// dispatch and ClangdServer together.
class ClangdLSPServer : private DiagnosticsConsumer, private ProtocolCallbacks {
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, const clangd::CodeCompleteOptions &CCOpts,
                  llvm::Optional<Path> CompileCommandsDir,
                  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
  /// class constructor. This method must not be executed more than once for
  /// each instance of ClangdLSPServer.
  ///
  /// \return Whether we received a 'shutdown' request before an 'exit' request.
  bool run(std::FILE *In,
           JSONStreamStyle InputStyle = JSONStreamStyle::Standard);

private:
  // Implement DiagnosticsConsumer.
  void onDiagnosticsReady(PathRef File, std::vector<Diag> Diagnostics) override;

  // Implement ProtocolCallbacks.
  void onInitialize(InitializeParams &Params) override;
  void onShutdown(ShutdownParams &Params) override;
  void onExit(ExitParams &Params) override;
  void onDocumentDidOpen(DidOpenTextDocumentParams &Params) override;
  void onDocumentDidChange(DidChangeTextDocumentParams &Params) override;
  void onDocumentDidClose(DidCloseTextDocumentParams &Params) override;
  void
  onDocumentOnTypeFormatting(DocumentOnTypeFormattingParams &Params) override;
  void
  onDocumentRangeFormatting(DocumentRangeFormattingParams &Params) override;
  void onDocumentFormatting(DocumentFormattingParams &Params) override;
  void onDocumentSymbol(DocumentSymbolParams &Params) override;
  void onCodeAction(CodeActionParams &Params) override;
  void onCompletion(TextDocumentPositionParams &Params) override;
  void onSignatureHelp(TextDocumentPositionParams &Params) override;
  void onGoToDefinition(TextDocumentPositionParams &Params) override;
  void onSwitchSourceHeader(TextDocumentIdentifier &Params) override;
  void onDocumentHighlight(TextDocumentPositionParams &Params) override;
  void onFileEvent(DidChangeWatchedFilesParams &Params) override;
  void onCommand(ExecuteCommandParams &Params) override;
  void onWorkspaceSymbol(WorkspaceSymbolParams &Params) override;
  void onRename(RenameParams &Parames) override;
  void onHover(TextDocumentPositionParams &Params) override;
  void onChangeConfiguration(DidChangeConfigurationParams &Params) override;

  std::vector<Fix> getFixes(StringRef File, const clangd::Diagnostic &D);

  /// Forces a reparse of all currently opened files.  As a result, this method
  /// may be very expensive.  This method is normally called when the
  /// compilation database is changed.
  void reparseOpenedFiles();

  JSONOutput &Out;
  /// Used to indicate that the 'shutdown' request was received from the
  /// Language Server client.
  bool ShutdownRequestReceived = false;

  /// Used to indicate that the 'exit' notification was received from the
  /// Language Server client.
  /// It's used to break out of the LSP parsing loop.
  bool IsDone = false;

  std::mutex FixItsMutex;
  typedef std::map<clangd::Diagnostic, std::vector<Fix>, LSPDiagnosticCompare>
      DiagnosticToReplacementMap;
  /// Caches FixIts per file and diagnostics
  llvm::StringMap<DiagnosticToReplacementMap> FixItsMap;

  // Various ClangdServer parameters go here. It's important they're created
  // before ClangdServer.
  DirectoryBasedGlobalCompilationDatabase NonCachedCDB;
  CachingCompilationDb CDB;

  RealFileSystemProvider FSProvider;
  /// Options used for code completion
  clangd::CodeCompleteOptions CCOpts;
  /// The supported kinds of the client.
  SymbolKindBitset SupportedSymbolKinds;

  // Store of the current versions of the open documents.
  DraftStore DraftMgr;

  // Server must be the last member of the class to allow its destructor to exit
  // the worker thread that may otherwise run an async callback on partially
  // destructed instance of ClangdLSPServer.
  ClangdServer Server;
};

} // namespace clangd
} // namespace clang

#endif
OpenPOWER on IntegriCloud