CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
181 lines
7.5 KiB
C++
181 lines
7.5 KiB
C++
//===--- Dex.h - Dex Symbol Index Implementation ----------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This defines Dex - a symbol index implementation based on query iterators
|
|
/// over symbol tokens, such as fuzzy matching trigrams, scopes, types, etc.
|
|
/// While consuming more memory and having longer build stage due to
|
|
/// preprocessing, Dex will have substantially lower latency. It will also allow
|
|
/// efficient symbol searching which is crucial for operations like code
|
|
/// completion, and can be very important for a number of different code
|
|
/// transformations which will be eventually supported by Clangd.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_DEX_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_DEX_H
|
|
|
|
#include "index/dex/Iterator.h"
|
|
#include "index/Index.h"
|
|
#include "index/Relation.h"
|
|
#include "index/dex/PostingList.h"
|
|
#include "index/dex/Token.h"
|
|
#include "llvm/ADT/StringSet.h"
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
namespace dex {
|
|
|
|
/// In-memory Dex trigram-based index implementation.
|
|
class Dex : public SymbolIndex {
|
|
public:
|
|
// All data must outlive this index.
|
|
template <typename SymbolRange, typename RefsRange, typename RelationsRange>
|
|
Dex(SymbolRange &&Symbols, RefsRange &&Refs, RelationsRange &&Relations,
|
|
bool SupportContainedRefs)
|
|
: Corpus(0) {
|
|
for (auto &&Sym : Symbols)
|
|
this->Symbols.push_back(&Sym);
|
|
for (auto &&Ref : Refs)
|
|
this->Refs.try_emplace(Ref.first, Ref.second);
|
|
for (auto &&Rel : Relations) {
|
|
this->Relations[std::make_pair(Rel.Subject,
|
|
static_cast<uint8_t>(Rel.Predicate))]
|
|
.push_back(Rel.Object);
|
|
if (Rel.Predicate == RelationKind::OverriddenBy) {
|
|
this->ReverseRelations[std::make_pair(Rel.Object, static_cast<uint8_t>(
|
|
Rel.Predicate))]
|
|
.push_back(Rel.Subject);
|
|
}
|
|
}
|
|
buildIndex(SupportContainedRefs);
|
|
}
|
|
// Symbols and Refs are owned by BackingData, Index takes ownership.
|
|
template <typename SymbolRange, typename RefsRange, typename RelationsRange,
|
|
typename Payload>
|
|
Dex(SymbolRange &&Symbols, RefsRange &&Refs, RelationsRange &&Relations,
|
|
Payload &&BackingData, size_t BackingDataSize, bool SupportContainedRefs)
|
|
: Dex(std::forward<SymbolRange>(Symbols), std::forward<RefsRange>(Refs),
|
|
std::forward<RelationsRange>(Relations), SupportContainedRefs) {
|
|
KeepAlive = std::shared_ptr<void>(
|
|
std::make_shared<Payload>(std::move(BackingData)), nullptr);
|
|
this->BackingDataSize = BackingDataSize;
|
|
}
|
|
|
|
template <typename SymbolRange, typename RefsRange, typename RelationsRange,
|
|
typename FileRange, typename Payload>
|
|
Dex(SymbolRange &&Symbols, RefsRange &&Refs, RelationsRange &&Relations,
|
|
FileRange &&Files, IndexContents IdxContents, Payload &&BackingData,
|
|
size_t BackingDataSize, bool SupportContainedRefs)
|
|
: Dex(std::forward<SymbolRange>(Symbols), std::forward<RefsRange>(Refs),
|
|
std::forward<RelationsRange>(Relations),
|
|
std::forward<Payload>(BackingData), BackingDataSize,
|
|
SupportContainedRefs) {
|
|
this->Files = std::forward<FileRange>(Files);
|
|
this->IdxContents = IdxContents;
|
|
}
|
|
|
|
/// Builds an index from slabs. The index takes ownership of the slab.
|
|
static std::unique_ptr<SymbolIndex> build(SymbolSlab, RefSlab, RelationSlab,
|
|
bool SupportContainedRefs);
|
|
|
|
bool
|
|
fuzzyFind(const FuzzyFindRequest &Req,
|
|
llvm::function_ref<void(const Symbol &)> Callback) const override;
|
|
|
|
void lookup(const LookupRequest &Req,
|
|
llvm::function_ref<void(const Symbol &)> Callback) const override;
|
|
|
|
bool refs(const RefsRequest &Req,
|
|
llvm::function_ref<void(const Ref &)> Callback) const override;
|
|
|
|
bool containedRefs(const ContainedRefsRequest &Req,
|
|
llvm::function_ref<void(const ContainedRefsResult &)>
|
|
Callback) const override;
|
|
|
|
void relations(const RelationsRequest &Req,
|
|
llvm::function_ref<void(const SymbolID &, const Symbol &)>
|
|
Callback) const override;
|
|
|
|
void
|
|
reverseRelations(const RelationsRequest &,
|
|
llvm::function_ref<void(const SymbolID &, const Symbol &)>)
|
|
const override;
|
|
|
|
llvm::unique_function<IndexContents(llvm::StringRef) const>
|
|
indexedFiles() const override;
|
|
|
|
size_t estimateMemoryUsage() const override;
|
|
|
|
private:
|
|
class RevRef {
|
|
const Ref *Reference;
|
|
SymbolID Target;
|
|
|
|
public:
|
|
RevRef(const Ref &Reference, SymbolID Target)
|
|
: Reference(&Reference), Target(Target) {}
|
|
const Ref &ref() const { return *Reference; }
|
|
ContainedRefsResult containedRefsResult() const {
|
|
return {ref().Location, ref().Kind, Target};
|
|
}
|
|
};
|
|
|
|
void buildIndex(bool EnableOutgoingCalls);
|
|
llvm::iterator_range<std::vector<RevRef>::const_iterator>
|
|
lookupRevRefs(const SymbolID &Container) const;
|
|
std::unique_ptr<Iterator> iterator(const Token &Tok) const;
|
|
std::unique_ptr<Iterator>
|
|
createFileProximityIterator(llvm::ArrayRef<std::string> ProximityPaths) const;
|
|
std::unique_ptr<Iterator>
|
|
createTypeBoostingIterator(llvm::ArrayRef<std::string> Types) const;
|
|
|
|
/// Stores symbols sorted in the descending order of symbol quality..
|
|
std::vector<const Symbol *> Symbols;
|
|
/// SymbolQuality[I] is the quality of Symbols[I].
|
|
std::vector<float> SymbolQuality;
|
|
llvm::DenseMap<SymbolID, const Symbol *> LookupTable;
|
|
/// Inverted index is a mapping from the search token to the posting list,
|
|
/// which contains all items which can be characterized by such search token.
|
|
/// For example, if the search token is scope "std::", the corresponding
|
|
/// posting list would contain all indices of symbols defined in namespace
|
|
/// std. Inverted index is used to retrieve posting lists which are processed
|
|
/// during the fuzzyFind process.
|
|
llvm::DenseMap<Token, PostingList> InvertedIndex;
|
|
dex::Corpus Corpus;
|
|
llvm::DenseMap<SymbolID, llvm::ArrayRef<Ref>> Refs;
|
|
std::vector<RevRef> RevRefs; // sorted by container ID
|
|
static_assert(sizeof(RelationKind) == sizeof(uint8_t),
|
|
"RelationKind should be of same size as a uint8_t");
|
|
llvm::DenseMap<std::pair<SymbolID, uint8_t>, std::vector<SymbolID>> Relations;
|
|
// Reverse relations, currently only for OverriddenBy
|
|
llvm::DenseMap<std::pair<SymbolID, uint8_t>, std::vector<SymbolID>>
|
|
ReverseRelations;
|
|
std::shared_ptr<void> KeepAlive; // poor man's move-only std::any
|
|
// Set of files which were used during this index build.
|
|
llvm::StringSet<> Files;
|
|
// Contents of the index (symbols, references, etc.)
|
|
// This is only populated if `Files` is, which applies to some but not all
|
|
// consumers of this class.
|
|
IndexContents IdxContents = IndexContents::None;
|
|
// Size of memory retained by KeepAlive.
|
|
size_t BackingDataSize = 0;
|
|
};
|
|
|
|
/// Returns Search Token for a number of parent directories of given Path.
|
|
/// Should be used within the index build process.
|
|
///
|
|
/// This function is exposed for testing only.
|
|
llvm::SmallVector<llvm::StringRef, 5> generateProximityURIs(llvm::StringRef);
|
|
|
|
} // namespace dex
|
|
} // namespace clangd
|
|
} // namespace clang
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_DEX_DEX_H
|