llvm-project

Форк
0
141 строка · 4.5 Кб
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

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);
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
142

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.