clang-tools 20.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
24namespace clang {
25namespace clangd {
26namespace {
27class ProjectAwareIndex : public SymbolIndex {
28public:
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 /// Query all indexes while prioritizing the associated one (if any).
39 bool containedRefs(const ContainedRefsRequest &Req,
40 llvm::function_ref<void(const ContainedRefsResult &)>
41 Callback) const override;
42
43 /// Queries only the associates index when Req.RestrictForCodeCompletion is
44 /// set, otherwise queries all.
45 bool
46 fuzzyFind(const FuzzyFindRequest &Req,
47 llvm::function_ref<void(const Symbol &)> Callback) const override;
48
49 /// Query all indexes while prioritizing the associated one (if any).
50 void relations(const RelationsRequest &Req,
51 llvm::function_ref<void(const SymbolID &, const Symbol &)>
52 Callback) const override;
53
54 llvm::unique_function<IndexContents(llvm::StringRef) const>
55 indexedFiles() const override;
56
57 ProjectAwareIndex(IndexFactory Gen, bool Sync) : Gen(std::move(Gen)) {
58 if (!Sync)
59 Tasks = std::make_unique<AsyncTaskRunner>();
60 }
61
62private:
63 // Returns the index associated with current context, if any.
64 SymbolIndex *getIndex() const;
65
66 // Storage for all the external indexes.
67 mutable std::mutex Mu;
68 mutable llvm::DenseMap<Config::ExternalIndexSpec,
69 std::unique_ptr<SymbolIndex>>
70 IndexForSpec;
71 mutable std::unique_ptr<AsyncTaskRunner> Tasks;
72
73 const IndexFactory Gen;
74};
75
76size_t ProjectAwareIndex::estimateMemoryUsage() const {
77 size_t Total = 0;
78 std::lock_guard<std::mutex> Lock(Mu);
79 for (auto &Entry : IndexForSpec)
80 Total += Entry.second->estimateMemoryUsage();
81 return Total;
82}
83
84void ProjectAwareIndex::lookup(
85 const LookupRequest &Req,
86 llvm::function_ref<void(const Symbol &)> Callback) const {
87 trace::Span Tracer("ProjectAwareIndex::lookup");
88 if (auto *Idx = getIndex())
89 Idx->lookup(Req, Callback);
90}
91
92bool ProjectAwareIndex::refs(
93 const RefsRequest &Req,
94 llvm::function_ref<void(const Ref &)> Callback) const {
95 trace::Span Tracer("ProjectAwareIndex::refs");
96 if (auto *Idx = getIndex())
97 return Idx->refs(Req, Callback);
98 return false;
99}
100
101bool ProjectAwareIndex::containedRefs(
102 const ContainedRefsRequest &Req,
103 llvm::function_ref<void(const ContainedRefsResult &)> Callback) const {
104 trace::Span Tracer("ProjectAwareIndex::refersTo");
105 if (auto *Idx = getIndex())
106 return Idx->containedRefs(Req, Callback);
107 return false;
108}
109
110bool ProjectAwareIndex::fuzzyFind(
111 const FuzzyFindRequest &Req,
112 llvm::function_ref<void(const Symbol &)> Callback) const {
113 trace::Span Tracer("ProjectAwareIndex::fuzzyFind");
114 if (auto *Idx = getIndex())
115 return Idx->fuzzyFind(Req, Callback);
116 return false;
117}
118
119void ProjectAwareIndex::relations(
120 const RelationsRequest &Req,
121 llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
122 trace::Span Tracer("ProjectAwareIndex::relations");
123 if (auto *Idx = getIndex())
124 return Idx->relations(Req, Callback);
125}
126
127llvm::unique_function<IndexContents(llvm::StringRef) const>
128ProjectAwareIndex::indexedFiles() const {
129 trace::Span Tracer("ProjectAwareIndex::indexedFiles");
130 if (auto *Idx = getIndex())
131 return Idx->indexedFiles();
132 return [](llvm::StringRef) { return IndexContents::None; };
133}
134
135SymbolIndex *ProjectAwareIndex::getIndex() const {
136 const auto &C = Config::current();
137 if (C.Index.External.Kind == Config::ExternalIndexSpec::None)
138 return nullptr;
139 const auto &External = C.Index.External;
140 std::lock_guard<std::mutex> Lock(Mu);
141 auto Entry = IndexForSpec.try_emplace(External, nullptr);
142 if (Entry.second)
143 Entry.first->getSecond() = Gen(External, Tasks.get());
144 return Entry.first->second.get();
145}
146} // namespace
147
148std::unique_ptr<SymbolIndex> createProjectAwareIndex(IndexFactory Gen,
149 bool Sync) {
150 assert(Gen);
151 return std::make_unique<ProjectAwareIndex>(std::move(Gen), Sync);
152}
153} // namespace clangd
154} // namespace clang
const Criteria C
IndexContents
Describes what data is covered by an index.
Definition: Index.h:114
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
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
std::unique_ptr< SymbolIndex > createProjectAwareIndex(IndexFactory Gen, bool Sync)
Returns an index that answers queries using external indices.
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Definition: TestIndex.cpp:151
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
Definition: Config.cpp:17