clang-tools 22.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 void
55 reverseRelations(const RelationsRequest &,
56 llvm::function_ref<void(const SymbolID &, const Symbol &)>)
57 const override;
58
59 llvm::unique_function<IndexContents(llvm::StringRef) const>
60 indexedFiles() const override;
61
62 ProjectAwareIndex(IndexFactory Gen, bool Sync) : Gen(std::move(Gen)) {
63 if (!Sync)
64 Tasks = std::make_unique<AsyncTaskRunner>();
65 }
66
67private:
68 // Returns the index associated with current context, if any.
69 SymbolIndex *getIndex() const;
70
71 // Storage for all the external indexes.
72 mutable std::mutex Mu;
73 mutable llvm::DenseMap<Config::ExternalIndexSpec,
74 std::unique_ptr<SymbolIndex>>
75 IndexForSpec;
76 mutable std::unique_ptr<AsyncTaskRunner> Tasks;
77
78 const IndexFactory Gen;
79};
80
81size_t ProjectAwareIndex::estimateMemoryUsage() const {
82 size_t Total = 0;
83 std::lock_guard<std::mutex> Lock(Mu);
84 for (auto &Entry : IndexForSpec)
85 Total += Entry.second->estimateMemoryUsage();
86 return Total;
87}
88
89void ProjectAwareIndex::lookup(
90 const LookupRequest &Req,
91 llvm::function_ref<void(const Symbol &)> Callback) const {
92 trace::Span Tracer("ProjectAwareIndex::lookup");
93 if (auto *Idx = getIndex())
94 Idx->lookup(Req, Callback);
95}
96
97bool ProjectAwareIndex::refs(
98 const RefsRequest &Req,
99 llvm::function_ref<void(const Ref &)> Callback) const {
100 trace::Span Tracer("ProjectAwareIndex::refs");
101 if (auto *Idx = getIndex())
102 return Idx->refs(Req, Callback);
103 return false;
104}
105
106bool ProjectAwareIndex::containedRefs(
107 const ContainedRefsRequest &Req,
108 llvm::function_ref<void(const ContainedRefsResult &)> Callback) const {
109 trace::Span Tracer("ProjectAwareIndex::refersTo");
110 if (auto *Idx = getIndex())
111 return Idx->containedRefs(Req, Callback);
112 return false;
113}
114
115bool ProjectAwareIndex::fuzzyFind(
116 const FuzzyFindRequest &Req,
117 llvm::function_ref<void(const Symbol &)> Callback) const {
118 trace::Span Tracer("ProjectAwareIndex::fuzzyFind");
119 if (auto *Idx = getIndex())
120 return Idx->fuzzyFind(Req, Callback);
121 return false;
122}
123
124void ProjectAwareIndex::relations(
125 const RelationsRequest &Req,
126 llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
127 trace::Span Tracer("ProjectAwareIndex::relations");
128 if (auto *Idx = getIndex())
129 return Idx->relations(Req, Callback);
130}
131
132void ProjectAwareIndex::reverseRelations(
133 const RelationsRequest &Req,
134 llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
135 trace::Span Tracer("ProjectAwareIndex::relations");
136 if (auto *Idx = getIndex())
137 return Idx->reverseRelations(Req, Callback);
138}
139
140llvm::unique_function<IndexContents(llvm::StringRef) const>
141ProjectAwareIndex::indexedFiles() const {
142 trace::Span Tracer("ProjectAwareIndex::indexedFiles");
143 if (auto *Idx = getIndex())
144 return Idx->indexedFiles();
145 return [](llvm::StringRef) { return IndexContents::None; };
146}
147
148SymbolIndex *ProjectAwareIndex::getIndex() const {
149 const auto &C = Config::current();
150 if (C.Index.External.Kind == Config::ExternalIndexSpec::None)
151 return nullptr;
152 const auto &External = C.Index.External;
153 std::lock_guard<std::mutex> Lock(Mu);
154 auto Entry = IndexForSpec.try_emplace(External, nullptr);
155 if (Entry.second)
156 Entry.first->getSecond() = Gen(External, Tasks.get());
157 return Entry.first->second.get();
158}
159} // namespace
160
161std::unique_ptr<SymbolIndex> createProjectAwareIndex(IndexFactory Gen,
162 bool Sync) {
163 assert(Gen);
164 return std::make_unique<ProjectAwareIndex>(std::move(Gen), Sync);
165}
166} // namespace clangd
167} // namespace clang
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
Definition Index.h:134
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:45
IndexContents
Describes what data is covered by an index.
Definition Index.h:114
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)
std::function< std::unique_ptr< SymbolIndex >( const Config::ExternalIndexSpec &, AsyncTaskRunner *)> IndexFactory
A functor to create an index for an external index specification.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//