clang-tools  14.0.0git
ProjectAware.cpp
Go to the documentation of this file.
1 //===--- ProjectAware.h ------------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ProjectAware.h"
10 #include "Config.h"
11 #include "index/Index.h"
12 #include "index/MemIndex.h"
13 #include "index/Merge.h"
14 #include "index/Ref.h"
15 #include "index/Serialization.h"
16 #include "index/Symbol.h"
17 #include "index/SymbolID.h"
18 #include "support/Logger.h"
19 #include "support/Threading.h"
20 #include "support/Trace.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include <map>
27 #include <memory>
28 #include <mutex>
29 #include <tuple>
30 
31 namespace clang {
32 namespace clangd {
33 namespace {
34 class ProjectAwareIndex : public SymbolIndex {
35 public:
36  size_t estimateMemoryUsage() const override;
37 
38  /// Only queries the associated index with the current context.
39  void lookup(const LookupRequest &Req,
40  llvm::function_ref<void(const Symbol &)> Callback) const override;
41 
42  /// Query all indexes while prioritizing the associated one (if any).
43  bool refs(const RefsRequest &Req,
44  llvm::function_ref<void(const Ref &)> Callback) const override;
45 
46  /// Queries only the associates index when Req.RestrictForCodeCompletion is
47  /// set, otherwise queries all.
48  bool
49  fuzzyFind(const FuzzyFindRequest &Req,
50  llvm::function_ref<void(const Symbol &)> Callback) const override;
51 
52  /// Query all indexes while prioritizing the associated one (if any).
53  void relations(const RelationsRequest &Req,
54  llvm::function_ref<void(const SymbolID &, const Symbol &)>
55  Callback) const override;
56 
57  llvm::unique_function<IndexContents(llvm::StringRef) const>
58  indexedFiles() const override;
59 
60  ProjectAwareIndex(IndexFactory Gen, bool Sync) : Gen(std::move(Gen)) {
61  if (!Sync)
62  Tasks = std::make_unique<AsyncTaskRunner>();
63  }
64 
65 private:
66  // Returns the index associated with current context, if any.
67  SymbolIndex *getIndex() const;
68 
69  // Storage for all the external indexes.
70  mutable std::mutex Mu;
71  mutable llvm::DenseMap<Config::ExternalIndexSpec,
72  std::unique_ptr<SymbolIndex>>
73  IndexForSpec;
74  mutable std::unique_ptr<AsyncTaskRunner> Tasks;
75 
76  const IndexFactory Gen;
77 };
78 
79 size_t ProjectAwareIndex::estimateMemoryUsage() const {
80  size_t Total = 0;
81  std::lock_guard<std::mutex> Lock(Mu);
82  for (auto &Entry : IndexForSpec)
83  Total += Entry.second->estimateMemoryUsage();
84  return Total;
85 }
86 
88  const LookupRequest &Req,
89  llvm::function_ref<void(const Symbol &)> Callback) const {
90  trace::Span Tracer("ProjectAwareIndex::lookup");
91  if (auto *Idx = getIndex())
92  Idx->lookup(Req, Callback);
93 }
94 
95 bool ProjectAwareIndex::refs(
96  const RefsRequest &Req,
97  llvm::function_ref<void(const Ref &)> Callback) const {
98  trace::Span Tracer("ProjectAwareIndex::refs");
99  if (auto *Idx = getIndex())
100  return Idx->refs(Req, Callback);
101  return false;
102 }
103 
104 bool ProjectAwareIndex::fuzzyFind(
105  const FuzzyFindRequest &Req,
106  llvm::function_ref<void(const Symbol &)> Callback) const {
107  trace::Span Tracer("ProjectAwareIndex::fuzzyFind");
108  if (auto *Idx = getIndex())
109  return Idx->fuzzyFind(Req, Callback);
110  return false;
111 }
112 
113 void ProjectAwareIndex::relations(
114  const RelationsRequest &Req,
115  llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
116  trace::Span Tracer("ProjectAwareIndex::relations");
117  if (auto *Idx = getIndex())
118  return Idx->relations(Req, Callback);
119 }
120 
121 llvm::unique_function<IndexContents(llvm::StringRef) const>
122 ProjectAwareIndex::indexedFiles() const {
123  trace::Span Tracer("ProjectAwareIndex::indexedFiles");
124  if (auto *Idx = getIndex())
125  return Idx->indexedFiles();
126  return [](llvm::StringRef) { return IndexContents::None; };
127 }
128 
129 SymbolIndex *ProjectAwareIndex::getIndex() const {
130  const auto &C = Config::current();
131  if (C.Index.External.Kind == Config::ExternalIndexSpec::None)
132  return nullptr;
133  const auto &External = C.Index.External;
134  std::lock_guard<std::mutex> Lock(Mu);
135  auto Entry = IndexForSpec.try_emplace(External, nullptr);
136  if (Entry.second)
137  Entry.first->getSecond() = Gen(External, Tasks.get());
138  return Entry.first->second.get();
139 }
140 } // namespace
141 
142 std::unique_ptr<SymbolIndex> createProjectAwareIndex(IndexFactory Gen,
143  bool Sync) {
144  assert(Gen);
145  return std::make_unique<ProjectAwareIndex>(std::move(Gen), Sync);
146 }
147 } // namespace clangd
148 } // namespace clang
Total
unsigned Total
Definition: FunctionCognitiveComplexityCheck.cpp:145
SymbolID.h
clang::clangd::createProjectAwareIndex
std::unique_ptr< SymbolIndex > createProjectAwareIndex(IndexFactory Gen, bool Sync)
Returns an index that answers queries using external indices.
Definition: ProjectAware.cpp:142
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:164
Index.h
Trace.h
ProjectAware.h
MemIndex.h
Logger.h
Threading.h
clang::clangd::IndexContents
IndexContents
Describes what data is covered by an index.
Definition: Index.h:91
clang::clangd::Config::ExternalIndexSpec::None
@ None
Definition: Config.h:73
Serialization.h
clang::doc::SymbolID
std::array< uint8_t, 20 > SymbolID
Definition: Representation.h:30
clang::clangd::lookup
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Definition: TestIndex.cpp:106
Symbol.h
Entry
Definition: Modularize.cpp:428
Config.h
clang::clangd::IndexContents::None
@ None
Ref.h
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::Config::current
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
Definition: Config.cpp:17
clang::clangd::Callback
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
Merge.h
clang::clangd::IndexFactory
std::function< std::unique_ptr< SymbolIndex >(const Config::ExternalIndexSpec &, AsyncTaskRunner *)> IndexFactory
A functor to create an index for an external index specification.
Definition: ProjectAware.h:25