llvm-project
80 строк · 2.5 Кб
1//===--- Symbol.cpp ----------------------------------------------*- 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 "Symbol.h"
10
11#include <cmath>
12
13namespace clang {
14namespace clangd {
15
16llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) {
17if (F == Symbol::None)
18return OS << "None";
19std::string S;
20if (F & Symbol::Deprecated)
21S += "deprecated|";
22if (F & Symbol::IndexedForCodeCompletion)
23S += "completion|";
24return OS << llvm::StringRef(S).rtrim('|');
25}
26
27llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) {
28return OS << S.Scope << S.Name;
29}
30
31float quality(const Symbol &S) {
32// This avoids a sharp gradient for tail symbols, and also neatly avoids the
33// question of whether 0 references means a bad symbol or missing data.
34if (S.References < 3)
35return 1;
36return std::log(S.References);
37}
38
39SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const {
40auto It = llvm::partition_point(Symbols,
41[&](const Symbol &S) { return S.ID < ID; });
42if (It != Symbols.end() && It->ID == ID)
43return It;
44return Symbols.end();
45}
46
47// Copy the underlying data of the symbol into the owned arena.
48static void own(Symbol &S, llvm::UniqueStringSaver &Strings) {
49visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); });
50}
51
52void SymbolSlab::Builder::insert(const Symbol &S) {
53own(Symbols[S.ID] = S, UniqueStrings);
54}
55
56SymbolSlab SymbolSlab::Builder::build() && {
57// Sort symbols into vector so the slab can binary search over them.
58std::vector<Symbol> SortedSymbols;
59SortedSymbols.reserve(Symbols.size());
60for (auto &Entry : Symbols)
61SortedSymbols.push_back(std::move(Entry.second));
62llvm::sort(SortedSymbols,
63[](const Symbol &L, const Symbol &R) { return L.ID < R.ID; });
64// We may have unused strings from overwritten symbols.
65// In practice, these are extremely small, it's not worth compacting.
66return SymbolSlab(std::move(Arena), std::move(SortedSymbols));
67}
68
69llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolSlab &Slab) {
70OS << "{";
71llvm::StringRef Sep = "";
72for (const auto &S : Slab) {
73OS << Sep << S;
74Sep = ", ";
75}
76OS << "}";
77return OS;
78}
79} // namespace clangd
80} // namespace clang
81