1 //===--- ProjectAware.h ------------------------------------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ProjectAware.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"
27 class ProjectAwareIndex
: public SymbolIndex
{
29 size_t estimateMemoryUsage() const override
;
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
;
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
;
39 /// Queries only the associates index when Req.RestrictForCodeCompletion is
40 /// set, otherwise queries all.
42 fuzzyFind(const FuzzyFindRequest
&Req
,
43 llvm::function_ref
<void(const Symbol
&)> Callback
) const override
;
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
;
50 llvm::unique_function
<IndexContents(llvm::StringRef
) const>
51 indexedFiles() const override
;
53 ProjectAwareIndex(IndexFactory Gen
, bool Sync
) : Gen(std::move(Gen
)) {
55 Tasks
= std::make_unique
<AsyncTaskRunner
>();
59 // Returns the index associated with current context, if any.
60 SymbolIndex
*getIndex() const;
62 // Storage for all the external indexes.
63 mutable std::mutex Mu
;
64 mutable llvm::DenseMap
<Config::ExternalIndexSpec
,
65 std::unique_ptr
<SymbolIndex
>>
67 mutable std::unique_ptr
<AsyncTaskRunner
> Tasks
;
69 const IndexFactory Gen
;
72 size_t ProjectAwareIndex::estimateMemoryUsage() const {
74 std::lock_guard
<std::mutex
> Lock(Mu
);
75 for (auto &Entry
: IndexForSpec
)
76 Total
+= Entry
.second
->estimateMemoryUsage();
80 void ProjectAwareIndex::lookup(
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
);
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
);
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
);
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
);
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
; };
122 SymbolIndex
*ProjectAwareIndex::getIndex() const {
123 const auto &C
= Config::current();
124 if (C
.Index
.External
.Kind
== Config::ExternalIndexSpec::None
)
126 const auto &External
= C
.Index
.External
;
127 std::lock_guard
<std::mutex
> Lock(Mu
);
128 auto Entry
= IndexForSpec
.try_emplace(External
, nullptr);
130 Entry
.first
->getSecond() = Gen(External
, Tasks
.get());
131 return Entry
.first
->second
.get();
135 std::unique_ptr
<SymbolIndex
> createProjectAwareIndex(IndexFactory Gen
,
138 return std::make_unique
<ProjectAwareIndex
>(std::move(Gen
), Sync
);
140 } // namespace clangd