clang-tools  15.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/Ref.h"
13 #include "index/Symbol.h"
14 #include "index/SymbolID.h"
15 #include "support/Threading.h"
16 #include "support/Trace.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include <map>
20 #include <memory>
21 #include <mutex>
22 #include <tuple>
23 
24 namespace clang {
25 namespace clangd {
26 namespace {
27 class ProjectAwareIndex : public SymbolIndex {
28 public:
29  size_t estimateMemoryUsage() const override;
30 
31  /// Only queries the associated index with the current context.
32  void lookup(const LookupRequest &Req,
33  llvm::function_ref<void(const Symbol &)> Callback) const override;
34 
35  /// Query all indexes while prioritizing the associated one (if any).
36  bool refs(const RefsRequest &Req,
37  llvm::function_ref<void(const Ref &)> Callback) const override;
38 
39  /// Queries only the associates index when Req.RestrictForCodeCompletion is
40  /// set, otherwise queries all.
41  bool
42  fuzzyFind(const FuzzyFindRequest &Req,
43  llvm::function_ref<void(const Symbol &)> Callback) const override;
44 
45  /// Query all indexes while prioritizing the associated one (if any).
46  void relations(const RelationsRequest &Req,
47  llvm::function_ref<void(const SymbolID &, const Symbol &)>
48  Callback) const override;
49 
50  llvm::unique_function<IndexContents(llvm::StringRef) const>
51  indexedFiles() const override;
52 
53  ProjectAwareIndex(IndexFactory Gen, bool Sync) : Gen(std::move(Gen)) {
54  if (!Sync)
55  Tasks = std::make_unique<AsyncTaskRunner>();
56  }
57 
58 private:
59  // Returns the index associated with current context, if any.
60  SymbolIndex *getIndex() const;
61 
62  // Storage for all the external indexes.
63  mutable std::mutex Mu;
64  mutable llvm::DenseMap<Config::ExternalIndexSpec,
65  std::unique_ptr<SymbolIndex>>
66  IndexForSpec;
67  mutable std::unique_ptr<AsyncTaskRunner> Tasks;
68 
69  const IndexFactory Gen;
70 };
71 
72 size_t ProjectAwareIndex::estimateMemoryUsage() const {
73  size_t Total = 0;
74  std::lock_guard<std::mutex> Lock(Mu);
75  for (auto &Entry : IndexForSpec)
76  Total += Entry.second->estimateMemoryUsage();
77  return Total;
78 }
79 
81  const LookupRequest &Req,
82  llvm::function_ref<void(const Symbol &)> Callback) const {
83  trace::Span Tracer("ProjectAwareIndex::lookup");
84  if (auto *Idx = getIndex())
85  Idx->lookup(Req, Callback);
86 }
87 
88 bool ProjectAwareIndex::refs(
89  const RefsRequest &Req,
90  llvm::function_ref<void(const Ref &)> Callback) const {
91  trace::Span Tracer("ProjectAwareIndex::refs");
92  if (auto *Idx = getIndex())
93  return Idx->refs(Req, Callback);
94  return false;
95 }
96 
97 bool ProjectAwareIndex::fuzzyFind(
98  const FuzzyFindRequest &Req,
99  llvm::function_ref<void(const Symbol &)> Callback) const {
100  trace::Span Tracer("ProjectAwareIndex::fuzzyFind");
101  if (auto *Idx = getIndex())
102  return Idx->fuzzyFind(Req, Callback);
103  return false;
104 }
105 
106 void ProjectAwareIndex::relations(
107  const RelationsRequest &Req,
108  llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
109  trace::Span Tracer("ProjectAwareIndex::relations");
110  if (auto *Idx = getIndex())
111  return Idx->relations(Req, Callback);
112 }
113 
114 llvm::unique_function<IndexContents(llvm::StringRef) const>
115 ProjectAwareIndex::indexedFiles() const {
116  trace::Span Tracer("ProjectAwareIndex::indexedFiles");
117  if (auto *Idx = getIndex())
118  return Idx->indexedFiles();
119  return [](llvm::StringRef) { return IndexContents::None; };
120 }
121 
122 SymbolIndex *ProjectAwareIndex::getIndex() const {
123  const auto &C = Config::current();
124  if (C.Index.External.Kind == Config::ExternalIndexSpec::None)
125  return nullptr;
126  const auto &External = C.Index.External;
127  std::lock_guard<std::mutex> Lock(Mu);
128  auto Entry = IndexForSpec.try_emplace(External, nullptr);
129  if (Entry.second)
130  Entry.first->getSecond() = Gen(External, Tasks.get());
131  return Entry.first->second.get();
132 }
133 } // namespace
134 
135 std::unique_ptr<SymbolIndex> createProjectAwareIndex(IndexFactory Gen,
136  bool Sync) {
137  assert(Gen);
138  return std::make_unique<ProjectAwareIndex>(std::move(Gen), Sync);
139 }
140 } // namespace clangd
141 } // 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:135
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:161
Index.h
Trace.h
ProjectAware.h
Threading.h
clang::clangd::IndexContents
IndexContents
Describes what data is covered by an index.
Definition: Index.h:93
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:136
Symbol.h
clang::clangd::Config::ExternalIndexSpec::None
@ None
Definition: Config.h:74
Entry
Definition: Modularize.cpp:427
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
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