brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · e9e02dd Raw
164 lines · cpp
1//===-- TestIndex.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "TestIndex.h"10#include "clang/Index/IndexSymbol.h"11#include "llvm/ADT/StringExtras.h"12#include "llvm/Support/Regex.h"13 14namespace clang {15namespace clangd {16 17Symbol symbol(llvm::StringRef QName) {18  Symbol Sym;19  Sym.ID = SymbolID(QName.str());20  size_t Pos = QName.rfind("::");21  if (Pos == llvm::StringRef::npos) {22    Sym.Name = QName;23    Sym.Scope = "";24  } else {25    Sym.Name = QName.substr(Pos + 2);26    Sym.Scope = QName.substr(0, Pos + 2);27  }28  return Sym;29}30 31static std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle,32                           llvm::StringRef Repl) {33  llvm::SmallVector<llvm::StringRef> Parts;34  Haystack.split(Parts, Needle);35  return llvm::join(Parts, Repl);36}37 38// Helpers to produce fake index symbols for memIndex() or completions().39// USRFormat is a regex replacement string for the unqualified part of the USR.40Symbol sym(llvm::StringRef QName, index::SymbolKind Kind,41           llvm::StringRef USRFormat, llvm::StringRef Signature) {42  Symbol Sym;43  std::string USR = "c:"; // We synthesize a few simple cases of USRs by hand!44  size_t Pos = QName.rfind("::");45  if (Pos == llvm::StringRef::npos) {46    Sym.Name = QName;47    Sym.Scope = "";48  } else {49    Sym.Name = QName.substr(Pos + 2);50    Sym.Scope = QName.substr(0, Pos + 2);51    USR += "@N@" + replace(QName.substr(0, Pos), "::", "@N@"); // ns:: -> @N@ns52  }53  USR += llvm::Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F@func#54  Sym.ID = SymbolID(USR);55  Sym.SymInfo.Kind = Kind;56  Sym.Flags |= Symbol::IndexedForCodeCompletion;57  Sym.Origin = SymbolOrigin::Static;58  Sym.Signature = Signature;59  return Sym;60}61 62Symbol func(llvm::StringRef Name) { // Assumes the function has no args.63  return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args64}65 66Symbol cls(llvm::StringRef Name) {67  return sym(Name, index::SymbolKind::Class, "@S@\\0");68}69 70Symbol enm(llvm::StringRef Name) {71  return sym(Name, index::SymbolKind::Enum, "@E@\\0");72}73 74Symbol enmConstant(llvm::StringRef Name) {75  return sym(Name, index::SymbolKind::EnumConstant, "@\\0");76}77 78Symbol var(llvm::StringRef Name) {79  return sym(Name, index::SymbolKind::Variable, "@\\0");80}81 82Symbol ns(llvm::StringRef Name) {83  return sym(Name, index::SymbolKind::Namespace, "@N@\\0");84}85 86Symbol conceptSym(llvm::StringRef Name) {87  return sym(Name, index::SymbolKind::Concept, "@CT@\\0");88}89 90Symbol macro(llvm::StringRef Name, llvm::StringRef ArgList) {91  return sym(Name, index::SymbolKind::Macro, "@macro@\\0", ArgList);92}93 94Symbol objcSym(llvm::StringRef Name, index::SymbolKind Kind,95               llvm::StringRef USRPrefix) {96  Symbol Sym;97  std::string USR = USRPrefix.str() + Name.str();98  Sym.Name = Name;99  Sym.Scope = "";100  Sym.ID = SymbolID(USR);101  Sym.SymInfo.Kind = Kind;102  Sym.SymInfo.Lang = index::SymbolLanguage::ObjC;103  Sym.Flags |= Symbol::IndexedForCodeCompletion;104  Sym.Origin = SymbolOrigin::Static;105  return Sym;106}107 108Symbol objcClass(llvm::StringRef Name) {109  return objcSym(Name, index::SymbolKind::Class, "objc(cs)");110}111 112Symbol objcCategory(llvm::StringRef Name, llvm::StringRef CategoryName) {113  std::string USRPrefix = ("objc(cy)" + Name + "@").str();114  return objcSym(CategoryName, index::SymbolKind::Extension, USRPrefix);115}116 117Symbol objcProtocol(llvm::StringRef Name) {118  return objcSym(Name, index::SymbolKind::Protocol, "objc(pl)");119}120 121SymbolSlab generateSymbols(std::vector<std::string> QualifiedNames) {122  SymbolSlab::Builder Slab;123  for (llvm::StringRef QName : QualifiedNames)124    Slab.insert(symbol(QName));125  return std::move(Slab).build();126}127 128SymbolSlab generateNumSymbols(int Begin, int End) {129  std::vector<std::string> Names;130  for (int I = Begin; I <= End; I++)131    Names.push_back(std::to_string(I));132  return generateSymbols(Names);133}134 135std::string getQualifiedName(const Symbol &Sym) {136  return (Sym.Scope + Sym.Name + Sym.TemplateSpecializationArgs).str();137}138 139std::vector<std::string> match(const SymbolIndex &I,140                               const FuzzyFindRequest &Req, bool *Incomplete) {141  std::vector<std::string> Matches;142  bool IsIncomplete = I.fuzzyFind(Req, [&](const Symbol &Sym) {143    Matches.push_back(clang::clangd::getQualifiedName(Sym));144  });145  if (Incomplete)146    *Incomplete = IsIncomplete;147  return Matches;148}149 150// Returns qualified names of symbols with any of IDs in the index.151std::vector<std::string> lookup(const SymbolIndex &I,152                                llvm::ArrayRef<SymbolID> IDs) {153  LookupRequest Req;154  Req.IDs.insert_range(IDs);155  std::vector<std::string> Results;156  I.lookup(Req, [&](const Symbol &Sym) {157    Results.push_back(getQualifiedName(Sym));158  });159  return Results;160}161 162} // namespace clangd163} // namespace clang164