clang-tools  7.0.0
SymbolYAML.cpp
Go to the documentation of this file.
1 //===--- SymbolYAML.cpp ------------------------------------------*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "SymbolYAML.h"
11 #include "Index.h"
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/Support/Errc.h"
14 #include "llvm/Support/MemoryBuffer.h"
15 #include "llvm/Support/raw_ostream.h"
16 
17 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(clang::clangd::Symbol)
18 
19 namespace llvm {
20 namespace yaml {
21 
26 using clang::index::SymbolLanguage;
28 
29 // Helper to (de)serialize the SymbolID. We serialize it as a hex string.
32  NormalizedSymbolID(IO &, const SymbolID& ID) {
33  llvm::raw_string_ostream OS(HexString);
34  OS << ID;
35  }
36 
38  SymbolID ID;
39  HexString >> ID;
40  return ID;
41  }
42 
43  std::string HexString;
44 };
45 
46 template <> struct MappingTraits<SymbolLocation::Position> {
47  static void mapping(IO &IO, SymbolLocation::Position &Value) {
48  IO.mapRequired("Line", Value.Line);
49  IO.mapRequired("Column", Value.Column);
50  }
51 };
52 
53 template <> struct MappingTraits<SymbolLocation> {
54  static void mapping(IO &IO, SymbolLocation &Value) {
55  IO.mapRequired("FileURI", Value.FileURI);
56  IO.mapRequired("Start", Value.Start);
57  IO.mapRequired("End", Value.End);
58  }
59 };
60 
61 template <> struct MappingTraits<SymbolInfo> {
62  static void mapping(IO &io, SymbolInfo &SymInfo) {
63  // FIXME: expose other fields?
64  io.mapRequired("Kind", SymInfo.Kind);
65  io.mapRequired("Lang", SymInfo.Lang);
66  }
67 };
68 
69 template <> struct MappingTraits<Symbol::Details> {
70  static void mapping(IO &io, Symbol::Details &Detail) {
71  io.mapOptional("Documentation", Detail.Documentation);
72  io.mapOptional("ReturnType", Detail.ReturnType);
73  io.mapOptional("IncludeHeader", Detail.IncludeHeader);
74  }
75 };
76 
77 // A YamlIO normalizer for fields of type "const T*" allocated on an arena.
78 // Normalizes to Optional<T>, so traits should be provided for T.
79 template <typename T> struct ArenaPtr {
80  ArenaPtr(IO &) {}
81  ArenaPtr(IO &, const T *D) {
82  if (D)
83  Opt = *D;
84  }
85 
86  const T *denormalize(IO &IO) {
87  assert(IO.getContext() && "Expecting an arena (as context) to allocate "
88  "data for read symbols.");
89  if (!Opt)
90  return nullptr;
91  return new (*static_cast<llvm::BumpPtrAllocator *>(IO.getContext()))
92  T(std::move(*Opt)); // Allocate a copy of Opt on the arena.
93  }
94 
95  llvm::Optional<T> Opt;
96 };
97 
98 template <> struct MappingTraits<Symbol> {
99  static void mapping(IO &IO, Symbol &Sym) {
100  MappingNormalization<NormalizedSymbolID, SymbolID> NSymbolID(IO, Sym.ID);
101  MappingNormalization<ArenaPtr<Symbol::Details>, const Symbol::Details *>
102  NDetail(IO, Sym.Detail);
103  IO.mapRequired("ID", NSymbolID->HexString);
104  IO.mapRequired("Name", Sym.Name);
105  IO.mapRequired("Scope", Sym.Scope);
106  IO.mapRequired("SymInfo", Sym.SymInfo);
107  IO.mapOptional("CanonicalDeclaration", Sym.CanonicalDeclaration,
108  SymbolLocation());
109  IO.mapOptional("Definition", Sym.Definition, SymbolLocation());
110  IO.mapOptional("References", Sym.References, 0u);
111  IO.mapOptional("IsIndexedForCodeCompletion", Sym.IsIndexedForCodeCompletion,
112  false);
113  IO.mapOptional("Signature", Sym.Signature);
114  IO.mapOptional("CompletionSnippetSuffix", Sym.CompletionSnippetSuffix);
115  IO.mapOptional("Detail", NDetail->Opt);
116  }
117 };
118 
119 template <> struct ScalarEnumerationTraits<SymbolLanguage> {
120  static void enumeration(IO &IO, SymbolLanguage &Value) {
121  IO.enumCase(Value, "C", SymbolLanguage::C);
122  IO.enumCase(Value, "Cpp", SymbolLanguage::CXX);
123  IO.enumCase(Value, "ObjC", SymbolLanguage::ObjC);
124  IO.enumCase(Value, "Swift", SymbolLanguage::Swift);
125  }
126 };
127 
128 template <> struct ScalarEnumerationTraits<SymbolKind> {
129  static void enumeration(IO &IO, SymbolKind &Value) {
130 #define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)
131 
132  DEFINE_ENUM(Unknown);
133  DEFINE_ENUM(Function);
134  DEFINE_ENUM(Module);
135  DEFINE_ENUM(Namespace);
136  DEFINE_ENUM(NamespaceAlias);
137  DEFINE_ENUM(Macro);
138  DEFINE_ENUM(Enum);
139  DEFINE_ENUM(Struct);
140  DEFINE_ENUM(Class);
141  DEFINE_ENUM(Protocol);
142  DEFINE_ENUM(Extension);
143  DEFINE_ENUM(Union);
144  DEFINE_ENUM(TypeAlias);
145  DEFINE_ENUM(Function);
146  DEFINE_ENUM(Variable);
147  DEFINE_ENUM(Field);
148  DEFINE_ENUM(EnumConstant);
149  DEFINE_ENUM(InstanceMethod);
150  DEFINE_ENUM(ClassMethod);
151  DEFINE_ENUM(StaticMethod);
152  DEFINE_ENUM(InstanceProperty);
153  DEFINE_ENUM(ClassProperty);
154  DEFINE_ENUM(StaticProperty);
155  DEFINE_ENUM(Constructor);
156  DEFINE_ENUM(Destructor);
157  DEFINE_ENUM(ConversionFunction);
158  DEFINE_ENUM(Parameter);
159  DEFINE_ENUM(Using);
160 
161 #undef DEFINE_ENUM
162  }
163 };
164 
165 } // namespace yaml
166 } // namespace llvm
167 
168 namespace clang {
169 namespace clangd {
170 
171 SymbolSlab symbolsFromYAML(llvm::StringRef YAMLContent) {
172  // Store data of pointer fields (excl. `StringRef`) like `Detail`.
173  llvm::BumpPtrAllocator Arena;
174  llvm::yaml::Input Yin(YAMLContent, &Arena);
175  std::vector<Symbol> S;
176  Yin >> S;
177 
178  SymbolSlab::Builder Syms;
179  for (auto &Sym : S)
180  Syms.insert(Sym);
181  return std::move(Syms).build();
182 }
183 
184 Symbol SymbolFromYAML(llvm::yaml::Input &Input, llvm::BumpPtrAllocator &Arena) {
185  // We could grab Arena out of Input, but it'd be a huge hazard for callers.
186  assert(Input.getContext() == &Arena);
187  Symbol S;
188  Input >> S;
189  return S;
190 }
191 
192 void SymbolsToYAML(const SymbolSlab& Symbols, llvm::raw_ostream &OS) {
193  llvm::yaml::Output Yout(OS);
194  for (Symbol S : Symbols) // copy: Yout<< requires mutability.
195  Yout << S;
196 }
197 
198 std::string SymbolToYAML(Symbol Sym) {
199  std::string Str;
200  llvm::raw_string_ostream OS(Str);
201  llvm::yaml::Output Yout(OS);
202  Yout << Sym;
203  return OS.str();
204 }
205 
206 } // namespace clangd
207 } // namespace clang
llvm::StringRef Documentation
Documentation including comment for the symbol declaration.
Definition: Index.h:208
llvm::Optional< T > Opt
Definition: SymbolYAML.cpp:95
ArenaPtr(IO &, const T *D)
Definition: SymbolYAML.cpp:81
Optional symbol details that are not required to be set.
Definition: Index.h:206
bool IsIndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.
Definition: Index.h:190
Some operations such as code completion produce a set of candidates.
static void mapping(IO &io, SymbolInfo &SymInfo)
Definition: SymbolYAML.cpp:62
llvm::StringRef IncludeHeader
This can be either a URI of the header to be #include&#39;d for this symbol, or a literal header quoted w...
Definition: Index.h:219
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
Definition: SymbolInfo.cpp:22
void insert(const Symbol &S)
Definition: Index.cpp:113
#define DEFINE_ENUM(name)
static void enumeration(IO &IO, SymbolKind &Value)
Definition: SymbolYAML.cpp:129
llvm::StringRef Scope
Definition: Index.h:172
llvm::StringRef ReturnType
Type when this symbol is used in an expression.
Definition: Index.h:211
unsigned References
Definition: Index.h:187
static void mapping(IO &IO, Symbol &Sym)
Definition: SymbolYAML.cpp:99
index::SymbolInfo SymInfo
Definition: Index.h:168
static void mapping(IO &IO, SymbolLocation::Position &Value)
Definition: SymbolYAML.cpp:47
SymbolLocation Definition
Definition: Index.h:175
clang::find_all_symbols::SymbolInfo SymbolInfo
static void mapping(IO &io, Symbol::Details &Detail)
Definition: SymbolYAML.cpp:70
llvm::StringRef Signature
A brief description of the symbol that can be appended in the completion candidate list...
Definition: Index.h:195
static void enumeration(IO &IO, SymbolLanguage &Value)
Definition: SymbolYAML.cpp:120
llvm::StringRef FileURI
Definition: Index.h:39
SymbolLocation CanonicalDeclaration
Definition: Index.h:184
void SymbolsToYAML(const SymbolSlab &Symbols, llvm::raw_ostream &OS)
Definition: SymbolYAML.cpp:192
std::string SymbolToYAML(Symbol Sym)
Definition: SymbolYAML.cpp:198
static void mapping(IO &IO, SymbolLocation &Value)
Definition: SymbolYAML.cpp:54
const T * denormalize(IO &IO)
Definition: SymbolYAML.cpp:86
Symbol SymbolFromYAML(llvm::yaml::Input &Input, llvm::BumpPtrAllocator &Arena)
Definition: SymbolYAML.cpp:184
Position Start
The symbol range, using half-open range [Start, End).
Definition: Index.h:42
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::StringRef Name
Definition: Index.h:170
const Details * Detail
Definition: Index.h:223
NormalizedSymbolID(IO &, const SymbolID &ID)
Definition: SymbolYAML.cpp:32
SymbolSlab symbolsFromYAML(llvm::StringRef YAMLContent)
Definition: SymbolYAML.cpp:171
llvm::StringRef CompletionSnippetSuffix
What to insert when completing this symbol, after the symbol name.
Definition: Index.h:199
std::array< uint8_t, 20 > SymbolID