brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 34d037b Raw
168 lines · cpp
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-exception6//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 is44  /// set, otherwise queries all.45  bool46  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  void55  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} // namespace160 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 clangd167} // namespace clang168