clang-tools  7.0.0
ClangdServer.cpp
Go to the documentation of this file.
1 //===--- ClangdServer.cpp - 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 #include "ClangdServer.h"
11 #include "CodeComplete.h"
12 #include "FindSymbols.h"
13 #include "Headers.h"
14 #include "SourceCode.h"
15 #include "XRefs.h"
16 #include "index/Merge.h"
17 #include "clang/Format/Format.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Frontend/CompilerInvocation.h"
20 #include "clang/Lex/Preprocessor.h"
21 #include "clang/Tooling/CompilationDatabase.h"
22 #include "clang/Tooling/Refactoring/RefactoringResultConsumer.h"
23 #include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/ADT/ScopeExit.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/Support/Errc.h"
28 #include "llvm/Support/FileSystem.h"
29 #include "llvm/Support/Path.h"
30 #include "llvm/Support/raw_ostream.h"
31 #include <future>
32 
33 using namespace clang;
34 using namespace clang::clangd;
35 
36 namespace {
37 
38 void ignoreError(llvm::Error Err) {
39  handleAllErrors(std::move(Err), [](const llvm::ErrorInfoBase &) {});
40 }
41 
42 std::string getStandardResourceDir() {
43  static int Dummy; // Just an address in this process.
44  return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy);
45 }
46 
47 class RefactoringResultCollector final
48  : public tooling::RefactoringResultConsumer {
49 public:
50  void handleError(llvm::Error Err) override {
51  assert(!Result.hasValue());
52  // FIXME: figure out a way to return better message for DiagnosticError.
53  // clangd uses llvm::toString to convert the Err to string, however, for
54  // DiagnosticError, only "clang diagnostic" will be generated.
55  Result = std::move(Err);
56  }
57 
58  // Using the handle(SymbolOccurrences) from parent class.
59  using tooling::RefactoringResultConsumer::handle;
60 
61  void handle(tooling::AtomicChanges SourceReplacements) override {
62  assert(!Result.hasValue());
63  Result = std::move(SourceReplacements);
64  }
65 
66  Optional<Expected<tooling::AtomicChanges>> Result;
67 };
68 
69 } // namespace
70 
73  Opts.UpdateDebounce = std::chrono::steady_clock::duration::zero(); // Faster!
74  Opts.StorePreamblesInMemory = true;
75  Opts.AsyncThreadsCount = 4; // Consistent!
76  return Opts;
77 }
78 
80  FileSystemProvider &FSProvider,
81  DiagnosticsConsumer &DiagConsumer,
82  const Options &Opts)
83  : CDB(CDB), DiagConsumer(DiagConsumer), FSProvider(FSProvider),
84  ResourceDir(Opts.ResourceDir ? Opts.ResourceDir->str()
85  : getStandardResourceDir()),
86  FileIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.URISchemes)
87  : nullptr),
88  PCHs(std::make_shared<PCHContainerOperations>()),
89  // Pass a callback into `WorkScheduler` to extract symbols from a newly
90  // parsed file and rebuild the file index synchronously each time an AST
91  // is parsed.
92  // FIXME(ioeric): this can be slow and we may be able to index on less
93  // critical paths.
94  WorkScheduler(
95  Opts.AsyncThreadsCount, Opts.StorePreamblesInMemory,
96  FileIdx
97  ? [this](PathRef Path, ASTContext &AST,
98  std::shared_ptr<Preprocessor>
99  PP) { FileIdx->update(Path, &AST, std::move(PP)); }
101  Opts.UpdateDebounce, Opts.RetentionPolicy) {
102  if (FileIdx && Opts.StaticIndex) {
103  MergedIndex = mergeIndex(FileIdx.get(), Opts.StaticIndex);
104  Index = MergedIndex.get();
105  } else if (FileIdx)
106  Index = FileIdx.get();
107  else if (Opts.StaticIndex)
108  Index = Opts.StaticIndex;
109  else
110  Index = nullptr;
111 }
112 
114  auto FS = FSProvider.getFileSystem();
115  auto Status = FS->status(RootPath);
116  if (!Status)
117  elog("Failed to get status for RootPath {0}: {1}", RootPath,
118  Status.getError().message());
119  else if (Status->isDirectory())
120  this->RootPath = RootPath;
121  else
122  elog("The provided RootPath {0} is not a directory.", RootPath);
123 }
124 
126  WantDiagnostics WantDiags) {
127  DocVersion Version = ++InternalVersion[File];
128  ParseInputs Inputs = {getCompileCommand(File), FSProvider.getFileSystem(),
129  Contents.str()};
130 
131  Path FileStr = File.str();
132  WorkScheduler.update(File, std::move(Inputs), WantDiags,
133  [this, FileStr, Version](std::vector<Diag> Diags) {
134  consumeDiagnostics(FileStr, Version, std::move(Diags));
135  });
136 }
137 
139  ++InternalVersion[File];
140  WorkScheduler.remove(File);
141 }
142 
144  const clangd::CodeCompleteOptions &Opts,
146  // Copy completion options for passing them to async task handler.
147  auto CodeCompleteOpts = Opts;
148  if (!CodeCompleteOpts.Index) // Respect overridden index.
149  CodeCompleteOpts.Index = Index;
150 
151  // Copy PCHs to avoid accessing this->PCHs concurrently
152  std::shared_ptr<PCHContainerOperations> PCHs = this->PCHs;
153  auto FS = FSProvider.getFileSystem();
154  auto Task = [PCHs, Pos, FS,
155  CodeCompleteOpts](Path File, Callback<CodeCompleteResult> CB,
156  llvm::Expected<InputsAndPreamble> IP) {
157  if (!IP)
158  return CB(IP.takeError());
159 
160  auto PreambleData = IP->Preamble;
161 
162  // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
163  // both the old and the new version in case only one of them matches.
165  File, IP->Command, PreambleData ? &PreambleData->Preamble : nullptr,
166  PreambleData ? PreambleData->Includes : IncludeStructure(),
167  IP->Contents, Pos, FS, PCHs, CodeCompleteOpts);
168  CB(std::move(Result));
169  };
170 
171  WorkScheduler.runWithPreamble("CodeComplete", File,
172  Bind(Task, File.str(), std::move(CB)));
173 }
174 
177 
178  auto PCHs = this->PCHs;
179  auto FS = FSProvider.getFileSystem();
180  auto Action = [Pos, FS, PCHs](Path File, Callback<SignatureHelp> CB,
181  llvm::Expected<InputsAndPreamble> IP) {
182  if (!IP)
183  return CB(IP.takeError());
184 
185  auto PreambleData = IP->Preamble;
186  CB(clangd::signatureHelp(File, IP->Command,
187  PreambleData ? &PreambleData->Preamble : nullptr,
188  IP->Contents, Pos, FS, PCHs));
189  };
190 
191  WorkScheduler.runWithPreamble("SignatureHelp", File,
192  Bind(Action, File.str(), std::move(CB)));
193 }
194 
195 llvm::Expected<tooling::Replacements>
197  llvm::Expected<size_t> Begin = positionToOffset(Code, Rng.start);
198  if (!Begin)
199  return Begin.takeError();
200  llvm::Expected<size_t> End = positionToOffset(Code, Rng.end);
201  if (!End)
202  return End.takeError();
203  return formatCode(Code, File, {tooling::Range(*Begin, *End - *Begin)});
204 }
205 
206 llvm::Expected<tooling::Replacements> ClangdServer::formatFile(StringRef Code,
207  PathRef File) {
208  // Format everything.
209  return formatCode(Code, File, {tooling::Range(0, Code.size())});
210 }
211 
212 llvm::Expected<tooling::Replacements>
214  // Look for the previous opening brace from the character position and
215  // format starting from there.
216  llvm::Expected<size_t> CursorPos = positionToOffset(Code, Pos);
217  if (!CursorPos)
218  return CursorPos.takeError();
219  size_t PreviousLBracePos = StringRef(Code).find_last_of('{', *CursorPos);
220  if (PreviousLBracePos == StringRef::npos)
221  PreviousLBracePos = *CursorPos;
222  size_t Len = *CursorPos - PreviousLBracePos;
223 
224  return formatCode(Code, File, {tooling::Range(PreviousLBracePos, Len)});
225 }
226 
227 void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
228  Callback<std::vector<tooling::Replacement>> CB) {
229  auto Action = [Pos](Path File, std::string NewName,
231  Expected<InputsAndAST> InpAST) {
232  if (!InpAST)
233  return CB(InpAST.takeError());
234  auto &AST = InpAST->AST;
235 
236  RefactoringResultCollector ResultCollector;
237  const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
238  SourceLocation SourceLocationBeg =
239  clangd::getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID());
240  tooling::RefactoringRuleContext Context(
241  AST.getASTContext().getSourceManager());
242  Context.setASTContext(AST.getASTContext());
243  auto Rename = clang::tooling::RenameOccurrences::initiate(
244  Context, SourceRange(SourceLocationBeg), NewName);
245  if (!Rename)
246  return CB(Rename.takeError());
247 
248  Rename->invoke(ResultCollector, Context);
249 
250  assert(ResultCollector.Result.hasValue());
251  if (!ResultCollector.Result.getValue())
252  return CB(ResultCollector.Result->takeError());
253 
254  std::vector<tooling::Replacement> Replacements;
255  for (const tooling::AtomicChange &Change : ResultCollector.Result->get()) {
256  tooling::Replacements ChangeReps = Change.getReplacements();
257  for (const auto &Rep : ChangeReps) {
258  // FIXME: Right now we only support renaming the main file, so we
259  // drop replacements not for the main file. In the future, we might
260  // consider to support:
261  // * rename in any included header
262  // * rename only in the "main" header
263  // * provide an error if there are symbols we won't rename (e.g.
264  // std::vector)
265  // * rename globally in project
266  // * rename in open files
267  if (Rep.getFilePath() == File)
268  Replacements.push_back(Rep);
269  }
270  }
271  return CB(std::move(Replacements));
272  };
273 
274  WorkScheduler.runWithAST(
275  "Rename", File, Bind(Action, File.str(), NewName.str(), std::move(CB)));
276 }
277 
279  llvm::unique_function<void(std::string)> Callback) {
280  auto Action = [](decltype(Callback) Callback,
281  llvm::Expected<InputsAndAST> InpAST) {
282  if (!InpAST) {
283  ignoreError(InpAST.takeError());
284  return Callback("<no-ast>");
285  }
286  std::string Result;
287 
288  llvm::raw_string_ostream ResultOS(Result);
289  clangd::dumpAST(InpAST->AST, ResultOS);
290  ResultOS.flush();
291 
292  Callback(Result);
293  };
294 
295  WorkScheduler.runWithAST("DumpAST", File, Bind(Action, std::move(Callback)));
296 }
297 
299  Callback<std::vector<Location>> CB) {
300  auto Action = [Pos, this](Callback<std::vector<Location>> CB,
301  llvm::Expected<InputsAndAST> InpAST) {
302  if (!InpAST)
303  return CB(InpAST.takeError());
304  CB(clangd::findDefinitions(InpAST->AST, Pos, Index));
305  };
306 
307  WorkScheduler.runWithAST("Definitions", File, Bind(Action, std::move(CB)));
308 }
309 
311 
312  StringRef SourceExtensions[] = {".cpp", ".c", ".cc", ".cxx",
313  ".c++", ".m", ".mm"};
314  StringRef HeaderExtensions[] = {".h", ".hh", ".hpp", ".hxx", ".inc"};
315 
316  StringRef PathExt = llvm::sys::path::extension(Path);
317 
318  // Lookup in a list of known extensions.
319  auto SourceIter =
320  std::find_if(std::begin(SourceExtensions), std::end(SourceExtensions),
321  [&PathExt](PathRef SourceExt) {
322  return SourceExt.equals_lower(PathExt);
323  });
324  bool IsSource = SourceIter != std::end(SourceExtensions);
325 
326  auto HeaderIter =
327  std::find_if(std::begin(HeaderExtensions), std::end(HeaderExtensions),
328  [&PathExt](PathRef HeaderExt) {
329  return HeaderExt.equals_lower(PathExt);
330  });
331 
332  bool IsHeader = HeaderIter != std::end(HeaderExtensions);
333 
334  // We can only switch between the known extensions.
335  if (!IsSource && !IsHeader)
336  return llvm::None;
337 
338  // Array to lookup extensions for the switch. An opposite of where original
339  // extension was found.
340  ArrayRef<StringRef> NewExts;
341  if (IsSource)
342  NewExts = HeaderExtensions;
343  else
344  NewExts = SourceExtensions;
345 
346  // Storage for the new path.
347  SmallString<128> NewPath = StringRef(Path);
348 
349  // Instance of vfs::FileSystem, used for file existence checks.
350  auto FS = FSProvider.getFileSystem();
351 
352  // Loop through switched extension candidates.
353  for (StringRef NewExt : NewExts) {
354  llvm::sys::path::replace_extension(NewPath, NewExt);
355  if (FS->exists(NewPath))
356  return NewPath.str().str(); // First str() to convert from SmallString to
357  // StringRef, second to convert from StringRef
358  // to std::string
359 
360  // Also check NewExt in upper-case, just in case.
361  llvm::sys::path::replace_extension(NewPath, NewExt.upper());
362  if (FS->exists(NewPath))
363  return NewPath.str().str();
364  }
365 
366  return llvm::None;
367 }
368 
369 llvm::Expected<tooling::Replacements>
370 ClangdServer::formatCode(llvm::StringRef Code, PathRef File,
371  ArrayRef<tooling::Range> Ranges) {
372  // Call clang-format.
373  auto FS = FSProvider.getFileSystem();
374  auto Style = format::getStyle(format::DefaultFormatStyle, File,
375  format::DefaultFallbackStyle, Code, FS.get());
376  if (!Style)
377  return Style.takeError();
378 
379  tooling::Replacements IncludeReplaces =
380  format::sortIncludes(*Style, Code, Ranges, File);
381  auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
382  if (!Changed)
383  return Changed.takeError();
384 
385  return IncludeReplaces.merge(format::reformat(
386  Style.get(), *Changed,
387  tooling::calculateRangesAfterReplacements(IncludeReplaces, Ranges),
388  File));
389 }
390 
392  PathRef File, Position Pos, Callback<std::vector<DocumentHighlight>> CB) {
394  llvm::Expected<InputsAndAST> InpAST) {
395  if (!InpAST)
396  return CB(InpAST.takeError());
397  CB(clangd::findDocumentHighlights(InpAST->AST, Pos));
398  };
399 
400  WorkScheduler.runWithAST("Highlights", File, Bind(Action, std::move(CB)));
401 }
402 
404  Callback<llvm::Optional<Hover>> CB) {
406  llvm::Expected<InputsAndAST> InpAST) {
407  if (!InpAST)
408  return CB(InpAST.takeError());
409  CB(clangd::getHover(InpAST->AST, Pos));
410  };
411 
412  WorkScheduler.runWithAST("Hover", File, Bind(Action, std::move(CB)));
413 }
414 
415 void ClangdServer::consumeDiagnostics(PathRef File, DocVersion Version,
416  std::vector<Diag> Diags) {
417  // We need to serialize access to resulting diagnostics to avoid calling
418  // `onDiagnosticsReady` in the wrong order.
419  std::lock_guard<std::mutex> DiagsLock(DiagnosticsMutex);
420  DocVersion &LastReportedDiagsVersion = ReportedDiagnosticVersions[File];
421 
422  // FIXME(ibiryukov): get rid of '<' comparison here. In the current
423  // implementation diagnostics will not be reported after version counters'
424  // overflow. This should not happen in practice, since DocVersion is a
425  // 64-bit unsigned integer.
426  if (Version < LastReportedDiagsVersion)
427  return;
428  LastReportedDiagsVersion = Version;
429 
430  DiagConsumer.onDiagnosticsReady(File, std::move(Diags));
431 }
432 
433 tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) {
434  llvm::Optional<tooling::CompileCommand> C = CDB.getCompileCommand(File);
435  if (!C) // FIXME: Suppress diagnostics? Let the user know?
436  C = CDB.getFallbackCommand(File);
437 
438  // Inject the resource dir.
439  // FIXME: Don't overwrite it if it's already there.
440  C->CommandLine.push_back("-resource-dir=" + ResourceDir);
441  return std::move(*C);
442 }
443 
445  // FIXME: Do nothing for now. This will be used for indexing and potentially
446  // invalidating other caches.
447 }
448 
450  StringRef Query, int Limit, Callback<std::vector<SymbolInformation>> CB) {
451  CB(clangd::getWorkspaceSymbols(Query, Limit, Index,
452  RootPath ? *RootPath : ""));
453 }
454 
456  StringRef File, Callback<std::vector<SymbolInformation>> CB) {
458  llvm::Expected<InputsAndAST> InpAST) {
459  if (!InpAST)
460  return CB(InpAST.takeError());
461  CB(clangd::getDocumentSymbols(InpAST->AST));
462  };
463  WorkScheduler.runWithAST("documentSymbols", File,
464  Bind(Action, std::move(CB)));
465 }
466 
467 std::vector<std::pair<Path, std::size_t>>
469  return WorkScheduler.getUsedBytesPerFile();
470 }
471 
472 LLVM_NODISCARD bool
473 ClangdServer::blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds) {
474  return WorkScheduler.blockUntilIdle(timeoutSeconds(TimeoutSeconds));
475 }
void rename(PathRef File, Position Pos, llvm::StringRef NewName, Callback< std::vector< tooling::Replacement >> CB)
Rename all occurrences of the symbol at the Pos in File to NewName.
Optional< Hover > getHover(ParsedAST &AST, Position Pos)
Get the hover information when hovering at Pos.
Definition: XRefs.cpp:652
WantDiagnostics
Determines whether diagnostics should be generated for a file snapshot.
Definition: TUScheduler.h:38
void setRootPath(PathRef RootPath)
Set the root path of the workspace.
std::vector< Location > findDefinitions(ParsedAST &AST, Position Pos, const SymbolIndex *Index)
Get definition of symbol at a specified Pos.
Definition: XRefs.cpp:216
llvm::Expected< tooling::Replacements > formatOnType(StringRef Code, PathRef File, Position Pos)
Run formatting after a character was typed at Pos in File with content Code.
Position start
The range&#39;s start position.
Definition: Protocol.h:120
CodeCompleteResult codeComplete(PathRef FileName, const tooling::CompileCommand &Command, PrecompiledPreamble const *Preamble, const IncludeStructure &PreambleInclusions, StringRef Contents, Position Pos, IntrusiveRefCntPtr< vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHs, CodeCompleteOptions Opts)
Get code completions at a specified Pos in FileName.
void documentSymbols(StringRef File, Callback< std::vector< SymbolInformation >> CB)
Retrieve the symbols within the specified file.
llvm::Expected< tooling::Replacements > formatRange(StringRef Code, PathRef File, Range Rng)
Run formatting for Rng inside File with content Code.
llvm::Expected< std::vector< SymbolInformation > > getDocumentSymbols(ParsedAST &AST)
Retrieves the symbols contained in the "main file" section of an AST in the same order that they appe...
std::function< void(PathRef Path, ASTContext &, std::shared_ptr< clang::Preprocessor >)> PreambleParsedCallback
Definition: ClangdUnit.h:131
bool blockUntilIdle(Deadline D) const
Wait until there are no scheduled or running tasks.
SignatureHelp signatureHelp(PathRef FileName, const tooling::CompileCommand &Command, PrecompiledPreamble const *Preamble, StringRef Contents, Position Pos, IntrusiveRefCntPtr< vfs::FileSystem > VFS, std::shared_ptr< PCHContainerOperations > PCHs)
Get signature help at a specified Pos in FileName.
void signatureHelp(PathRef File, Position Pos, Callback< SignatureHelp > CB)
Provide signature help for File at Pos.
void remove(PathRef File)
Remove File from the list of tracked files and schedule removal of its resources. ...
void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS)
For testing/debugging purposes.
Definition: ClangdUnit.cpp:119
std::vector< std::pair< Path, std::size_t > > getUsedBytesPerFile() const
Returns estimated memory usage for each of the currently open files.
virtual llvm::Optional< tooling::CompileCommand > getCompileCommand(PathRef File) const =0
If there are any known-good commands for building this file, returns one.
LLVM_NODISCARD bool blockUntilIdleForTest(llvm::Optional< double > TimeoutSeconds=10)
This manages symbls from files and an in-memory index on all symbols.
Definition: FileIndex.h:57
static Options optsForTest()
llvm::Expected< std::vector< SymbolInformation > > getWorkspaceSymbols(StringRef Query, int Limit, const SymbolIndex *const Index, StringRef HintPath)
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:24
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
virtual IntrusiveRefCntPtr< vfs::FileSystem > getFileSystem()=0
Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing.
Documents should not be synced at all.
unsigned AsyncThreadsCount
To process requests asynchronously, ClangdServer spawns worker threads.
Definition: ClangdServer.h:55
void findHover(PathRef File, Position Pos, Callback< llvm::Optional< Hover >> CB)
Get code hover for a given position.
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:56
StringRef Contents
void addDocument(PathRef File, StringRef Contents, WantDiagnostics WD=WantDiagnostics::Auto)
Add a File to the list of tracked C++ files or update the contents if File is already tracked...
llvm::Expected< size_t > positionToOffset(StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Definition: SourceCode.cpp:83
Provides compilation arguments used for parsing C and C++ files.
void findDefinitions(PathRef File, Position Pos, Callback< std::vector< Location >> CB)
Get definition of symbol at a specified Line and Column in File.
llvm::Optional< Path > switchSourceHeader(PathRef Path)
Helper function that returns a path to the corresponding source file when given a header file and vic...
static llvm::cl::opt< Path > ResourceDir("resource-dir", llvm::cl::desc("Directory for system clang headers"), llvm::cl::init(""), llvm::cl::Hidden)
ForwardBinder< Func, Args... > Bind(Func F, Args &&... As)
Creates an object that stores a callable (F) and first arguments to the callable (As) and allows to c...
Definition: Function.h:81
ClangdServer(GlobalCompilationDatabase &CDB, FileSystemProvider &FSProvider, DiagnosticsConsumer &DiagConsumer, const Options &Opts)
Creates a new ClangdServer instance.
llvm::unique_function< void()> Action
void removeDocument(PathRef File)
Remove File from list of tracked files, schedule a request to free resources associated with it...
std::string Path
A typedef to represent a file path.
Definition: Path.h:21
virtual void onDiagnosticsReady(PathRef File, std::vector< Diag > Diagnostics)=0
Called by ClangdServer when Diagnostics for File are ready.
llvm::Expected< tooling::Replacements > formatFile(StringRef Code, PathRef File)
Run formatting for the whole File with content Code.
std::vector< std::pair< Path, std::size_t > > getUsedBytesPerFile() const
Returns estimated memory usage for each of the currently open files.
std::chrono::steady_clock::duration UpdateDebounce
Time to wait after a new file version before computing diagnostics.
Definition: ClangdServer.h:81
std::vector< DocumentHighlight > findDocumentHighlights(ParsedAST &AST, Position Pos)
Returns highlights for all usages of a symbol at Pos.
Definition: XRefs.cpp:391
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:70
Position Pos
void update(PathRef File, ParseInputs Inputs, WantDiagnostics WD, llvm::unique_function< void(std::vector< Diag >)> OnUpdated)
Schedule an update for File.
const SymbolIndex * Index
If Index is set, it is used to augment the code completion results.
Definition: CodeComplete.h:79
void codeComplete(PathRef File, Position Pos, const clangd::CodeCompleteOptions &Opts, Callback< CodeCompleteResult > CB)
Run code completion for File at Pos.
Information required to run clang, e.g. to parse AST or do code completion.
Definition: ClangdUnit.h:59
void runWithPreamble(llvm::StringRef Name, PathRef File, Callback< InputsAndPreamble > Action)
Schedule an async read of the Preamble.
bool StorePreamblesInMemory
Cached preambles are potentially large. If false, store them on disk.
Definition: ClangdServer.h:61
SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, const FileID FID)
Get the beginning SourceLocation at a specified Pos.
Definition: ClangdUnit.cpp:375
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Deadline timeoutSeconds(llvm::Optional< double > Seconds)
Makes a deadline from a timeout in seconds. None means wait forever.
Definition: Threading.cpp:82
void workspaceSymbols(StringRef Query, int Limit, Callback< std::vector< SymbolInformation >> CB)
Retrieve the top symbols from the workspace matching a query.
std::shared_ptr< PCHContainerOperations > PCHs
CharSourceRange Range
SourceRange for the file name.
void runWithAST(llvm::StringRef Name, PathRef File, Callback< InputsAndAST > Action)
Schedule an async read of the AST.
void dumpAST(PathRef File, llvm::unique_function< void(std::string)> Callback)
Only for testing purposes.
PrecompiledPreamble Preamble
Definition: ClangdUnit.h:51
Position end
The range&#39;s end position.
Definition: Protocol.h:123
void findDocumentHighlights(PathRef File, Position Pos, Callback< std::vector< DocumentHighlight >> CB)
Get document highlights for a given position.
void onFileEvent(const DidChangeWatchedFilesParams &Params)
Called when an event occurs for a watched file in the workspace.
virtual tooling::CompileCommand getFallbackCommand(PathRef File) const
Makes a guess at how to build a file.
std::unique_ptr< SymbolIndex > mergeIndex(const SymbolIndex *Dynamic, const SymbolIndex *Static)
Definition: Merge.cpp:123