clang-tools  15.0.0git
Protocol.cpp
Go to the documentation of this file.
1 //===--- Protocol.cpp - Language Server Protocol Implementation -----------===//
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 // This file contains the serialization code for the LSP structs.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "Protocol.h"
14 #include "URI.h"
15 #include "support/Logger.h"
16 #include "clang/Basic/LLVM.h"
17 #include "clang/Index/IndexSymbol.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/JSON.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 namespace clang {
26 namespace clangd {
27 namespace {
28 
29 // Helper that doesn't treat `null` and absent fields as failures.
30 template <typename T>
31 bool mapOptOrNull(const llvm::json::Value &Params, llvm::StringLiteral Prop,
32  T &Out, llvm::json::Path P) {
33  auto *O = Params.getAsObject();
34  assert(O);
35  auto *V = O->get(Prop);
36  // Field is missing or null.
37  if (!V || V->getAsNull().hasValue())
38  return true;
39  return fromJSON(*V, Out, P.field(Prop));
40 }
41 } // namespace
42 
43 char LSPError::ID;
44 
45 URIForFile URIForFile::canonicalize(llvm::StringRef AbsPath,
46  llvm::StringRef TUPath) {
47  assert(llvm::sys::path::is_absolute(AbsPath) && "the path is relative");
48  auto Resolved = URI::resolvePath(AbsPath, TUPath);
49  if (!Resolved) {
50  elog("URIForFile: failed to resolve path {0} with TU path {1}: "
51  "{2}.\nUsing unresolved path.",
52  AbsPath, TUPath, Resolved.takeError());
53  return URIForFile(std::string(AbsPath));
54  }
55  return URIForFile(std::move(*Resolved));
56 }
57 
58 llvm::Expected<URIForFile> URIForFile::fromURI(const URI &U,
59  llvm::StringRef HintPath) {
60  auto Resolved = URI::resolve(U, HintPath);
61  if (!Resolved)
62  return Resolved.takeError();
63  return URIForFile(std::move(*Resolved));
64 }
65 
67  if (auto S = E.getAsString()) {
68  auto Parsed = URI::parse(*S);
69  if (!Parsed) {
70  consumeError(Parsed.takeError());
71  P.report("failed to parse URI");
72  return false;
73  }
74  if (Parsed->scheme() != "file" && Parsed->scheme() != "test") {
75  P.report("clangd only supports 'file' URI scheme for workspace files");
76  return false;
77  }
78  // "file" and "test" schemes do not require hint path.
79  auto U = URIForFile::fromURI(*Parsed, /*HintPath=*/"");
80  if (!U) {
81  P.report("unresolvable URI");
82  consumeError(U.takeError());
83  return false;
84  }
85  R = std::move(*U);
86  return true;
87  }
88  return false;
89 }
90 
91 llvm::json::Value toJSON(const URIForFile &U) { return U.uri(); }
92 
93 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const URIForFile &U) {
94  return OS << U.uri();
95 }
96 
98  return llvm::json::Object{{"uri", R.uri}};
99 }
100 
102  llvm::json::Path P) {
103  llvm::json::ObjectMapper O(Params, P);
104  return O && O.map("uri", R.uri);
105 }
106 
108  auto Result = toJSON(static_cast<const TextDocumentIdentifier &>(R));
109  Result.getAsObject()->try_emplace("version", R.version);
110  return Result;
111 }
112 
113 bool fromJSON(const llvm::json::Value &Params,
115  llvm::json::ObjectMapper O(Params, P);
116  return fromJSON(Params, static_cast<TextDocumentIdentifier &>(R), P) && O &&
117  O.map("version", R.version);
118 }
119 
120 bool fromJSON(const llvm::json::Value &Params, Position &R,
121  llvm::json::Path P) {
122  llvm::json::ObjectMapper O(Params, P);
123  return O && O.map("line", R.line) && O.map("character", R.character);
124 }
125 
127  return llvm::json::Object{
128  {"line", P.line},
129  {"character", P.character},
130  };
131 }
132 
133 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Position &P) {
134  return OS << P.line << ':' << P.character;
135 }
136 
137 bool fromJSON(const llvm::json::Value &Params, Range &R, llvm::json::Path P) {
138  llvm::json::ObjectMapper O(Params, P);
139  return O && O.map("start", R.start) && O.map("end", R.end);
140 }
141 
143  return llvm::json::Object{
144  {"start", P.start},
145  {"end", P.end},
146  };
147 }
148 
149 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Range &R) {
150  return OS << R.start << '-' << R.end;
151 }
152 
154  return llvm::json::Object{
155  {"uri", P.uri},
156  {"range", P.range},
157  };
158 }
159 
160 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Location &L) {
161  return OS << L.range << '@' << L.uri;
162 }
163 
165  llvm::json::Path P) {
166  llvm::json::ObjectMapper O(Params, P);
167  return O && O.map("uri", R.uri) && O.map("languageId", R.languageId) &&
168  O.map("version", R.version) && O.map("text", R.text);
169 }
170 
171 bool fromJSON(const llvm::json::Value &Params, TextEdit &R,
172  llvm::json::Path P) {
173  llvm::json::ObjectMapper O(Params, P);
174  return O && O.map("range", R.range) && O.map("newText", R.newText);
175 }
176 
178  return llvm::json::Object{
179  {"range", P.range},
180  {"newText", P.newText},
181  };
182 }
183 
184 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TextEdit &TE) {
185  OS << TE.range << " => \"";
186  llvm::printEscapedString(TE.newText, OS);
187  return OS << '"';
188 }
189 
191  if (auto S = E.getAsString()) {
192  if (*S == "off") {
194  return true;
195  }
196  if (*S == "messages") {
198  return true;
199  }
200  if (*S == "verbose") {
202  return true;
203  }
204  }
205  return false;
206 }
207 
209  if (auto T = E.getAsInteger()) {
210  if (*T < static_cast<int>(SymbolKind::File) ||
211  *T > static_cast<int>(SymbolKind::TypeParameter))
212  return false;
213  Out = static_cast<SymbolKind>(*T);
214  return true;
215  }
216  return false;
217 }
218 
220  llvm::json::Path P) {
221  if (auto *A = E.getAsArray()) {
222  for (size_t I = 0; I < A->size(); ++I) {
223  SymbolKind KindOut;
224  if (fromJSON((*A)[I], KindOut, P.index(I)))
225  Out.set(size_t(KindOut));
226  }
227  return true;
228  }
229  return false;
230 }
231 
233  SymbolKindBitset &SupportedSymbolKinds) {
234  auto KindVal = static_cast<size_t>(Kind);
235  if (KindVal >= SymbolKindMin && KindVal <= SupportedSymbolKinds.size() &&
236  SupportedSymbolKinds[KindVal])
237  return Kind;
238 
239  switch (Kind) {
240  // Provide some fall backs for common kinds that are close enough.
241  case SymbolKind::Struct:
242  return SymbolKind::Class;
244  return SymbolKind::Enum;
245  default:
246  return SymbolKind::String;
247  }
248 }
249 
251  switch (Kind) {
253  return SymbolKind::Variable;
254  case index::SymbolKind::Module:
255  return SymbolKind::Module;
256  case index::SymbolKind::Namespace:
257  return SymbolKind::Namespace;
258  case index::SymbolKind::NamespaceAlias:
259  return SymbolKind::Namespace;
260  case index::SymbolKind::Macro:
261  return SymbolKind::String;
262  case index::SymbolKind::Enum:
263  return SymbolKind::Enum;
264  case index::SymbolKind::Struct:
265  return SymbolKind::Struct;
266  case index::SymbolKind::Class:
267  return SymbolKind::Class;
268  case index::SymbolKind::Protocol:
269  return SymbolKind::Interface;
270  case index::SymbolKind::Extension:
271  return SymbolKind::Interface;
272  case index::SymbolKind::Union:
273  return SymbolKind::Class;
274  case index::SymbolKind::TypeAlias:
275  return SymbolKind::Class;
276  case index::SymbolKind::Function:
277  return SymbolKind::Function;
278  case index::SymbolKind::Variable:
279  return SymbolKind::Variable;
281  return SymbolKind::Field;
282  case index::SymbolKind::EnumConstant:
283  return SymbolKind::EnumMember;
284  case index::SymbolKind::InstanceMethod:
285  case index::SymbolKind::ClassMethod:
286  case index::SymbolKind::StaticMethod:
287  return SymbolKind::Method;
288  case index::SymbolKind::InstanceProperty:
289  case index::SymbolKind::ClassProperty:
290  case index::SymbolKind::StaticProperty:
291  return SymbolKind::Property;
292  case index::SymbolKind::Constructor:
293  case index::SymbolKind::Destructor:
295  case index::SymbolKind::ConversionFunction:
296  return SymbolKind::Function;
297  case index::SymbolKind::Parameter:
298  case index::SymbolKind::NonTypeTemplateParm:
299  return SymbolKind::Variable;
300  case index::SymbolKind::Using:
301  return SymbolKind::Namespace;
302  case index::SymbolKind::TemplateTemplateParm:
303  case index::SymbolKind::TemplateTypeParm:
305  case index::SymbolKind::Concept:
306  return SymbolKind::Interface;
307  }
308  llvm_unreachable("invalid symbol kind");
309 }
310 
312  llvm::json::Path P) {
313  const llvm::json::Object *O = Params.getAsObject();
314  if (!O) {
315  P.report("expected object");
316  return false;
317  }
318  if (auto *TextDocument = O->getObject("textDocument")) {
319  if (auto *SemanticHighlighting =
320  TextDocument->getObject("semanticHighlightingCapabilities")) {
321  if (auto SemanticHighlightingSupport =
322  SemanticHighlighting->getBoolean("semanticHighlighting"))
323  R.TheiaSemanticHighlighting = *SemanticHighlightingSupport;
324  }
325  if (TextDocument->getObject("semanticTokens"))
326  R.SemanticTokens = true;
327  if (auto *Diagnostics = TextDocument->getObject("publishDiagnostics")) {
328  if (auto CategorySupport = Diagnostics->getBoolean("categorySupport"))
329  R.DiagnosticCategory = *CategorySupport;
330  if (auto CodeActions = Diagnostics->getBoolean("codeActionsInline"))
331  R.DiagnosticFixes = *CodeActions;
332  if (auto RelatedInfo = Diagnostics->getBoolean("relatedInformation"))
333  R.DiagnosticRelatedInformation = *RelatedInfo;
334  }
335  if (auto *Completion = TextDocument->getObject("completion")) {
336  if (auto *Item = Completion->getObject("completionItem")) {
337  if (auto SnippetSupport = Item->getBoolean("snippetSupport"))
338  R.CompletionSnippets = *SnippetSupport;
339  if (const auto *DocumentationFormat =
340  Item->getArray("documentationFormat")) {
341  for (const auto &Format : *DocumentationFormat) {
342  if (fromJSON(Format, R.CompletionDocumentationFormat, P))
343  break;
344  }
345  }
346  }
347  if (auto *ItemKind = Completion->getObject("completionItemKind")) {
348  if (auto *ValueSet = ItemKind->get("valueSet")) {
349  R.CompletionItemKinds.emplace();
350  if (!fromJSON(*ValueSet, *R.CompletionItemKinds,
351  P.field("textDocument")
352  .field("completion")
353  .field("completionItemKind")
354  .field("valueSet")))
355  return false;
356  }
357  }
358  if (auto EditsNearCursor = Completion->getBoolean("editsNearCursor"))
359  R.CompletionFixes = *EditsNearCursor;
360  }
361  if (auto *CodeAction = TextDocument->getObject("codeAction")) {
362  if (CodeAction->getObject("codeActionLiteralSupport"))
363  R.CodeActionStructure = true;
364  }
365  if (auto *DocumentSymbol = TextDocument->getObject("documentSymbol")) {
366  if (auto HierarchicalSupport =
367  DocumentSymbol->getBoolean("hierarchicalDocumentSymbolSupport"))
368  R.HierarchicalDocumentSymbol = *HierarchicalSupport;
369  }
370  if (auto *Hover = TextDocument->getObject("hover")) {
371  if (auto *ContentFormat = Hover->getArray("contentFormat")) {
372  for (const auto &Format : *ContentFormat) {
373  if (fromJSON(Format, R.HoverContentFormat, P))
374  break;
375  }
376  }
377  }
378  if (auto *Help = TextDocument->getObject("signatureHelp")) {
379  R.HasSignatureHelp = true;
380  if (auto *Info = Help->getObject("signatureInformation")) {
381  if (auto *Parameter = Info->getObject("parameterInformation")) {
382  if (auto OffsetSupport = Parameter->getBoolean("labelOffsetSupport"))
383  R.OffsetsInSignatureHelp = *OffsetSupport;
384  }
385  if (const auto *DocumentationFormat =
386  Info->getArray("documentationFormat")) {
387  for (const auto &Format : *DocumentationFormat) {
388  if (fromJSON(Format, R.SignatureHelpDocumentationFormat, P))
389  break;
390  }
391  }
392  }
393  }
394  if (auto *Rename = TextDocument->getObject("rename")) {
395  if (auto RenameSupport = Rename->getBoolean("prepareSupport"))
396  R.RenamePrepareSupport = *RenameSupport;
397  }
398  }
399  if (auto *Workspace = O->getObject("workspace")) {
400  if (auto *Symbol = Workspace->getObject("symbol")) {
401  if (auto *SymbolKind = Symbol->getObject("symbolKind")) {
402  if (auto *ValueSet = SymbolKind->get("valueSet")) {
403  R.WorkspaceSymbolKinds.emplace();
404  if (!fromJSON(*ValueSet, *R.WorkspaceSymbolKinds,
405  P.field("workspace")
406  .field("symbol")
407  .field("symbolKind")
408  .field("valueSet")))
409  return false;
410  }
411  }
412  }
413  if (auto *SemanticTokens = Workspace->getObject("semanticTokens")) {
414  if (auto RefreshSupport = SemanticTokens->getBoolean("refreshSupport"))
415  R.SemanticTokenRefreshSupport = *RefreshSupport;
416  }
417  }
418  if (auto *Window = O->getObject("window")) {
419  if (auto WorkDoneProgress = Window->getBoolean("workDoneProgress"))
420  R.WorkDoneProgress = *WorkDoneProgress;
421  if (auto Implicit = Window->getBoolean("implicitWorkDoneProgressCreate"))
422  R.ImplicitProgressCreation = *Implicit;
423  }
424  if (auto *General = O->getObject("general")) {
425  if (auto *StaleRequestSupport = General->getObject("staleRequestSupport")) {
426  if (auto Cancel = StaleRequestSupport->getBoolean("cancel"))
427  R.CancelsStaleRequests = *Cancel;
428  }
429  }
430  if (auto *OffsetEncoding = O->get("offsetEncoding")) {
431  R.offsetEncoding.emplace();
433  P.field("offsetEncoding")))
434  return false;
435  }
436  return true;
437 }
438 
440  llvm::json::Path P) {
441  llvm::json::ObjectMapper O(Params, P);
442  if (!O)
443  return false;
444  // We deliberately don't fail if we can't parse individual fields.
445  // Failing to handle a slightly malformed initialize would be a disaster.
446  O.map("processId", R.processId);
447  O.map("rootUri", R.rootUri);
448  O.map("rootPath", R.rootPath);
449  O.map("capabilities", R.capabilities);
450  if (auto *RawCaps = Params.getAsObject()->getObject("capabilities"))
451  R.rawCapabilities = *RawCaps;
452  O.map("trace", R.trace);
453  O.map("initializationOptions", R.initializationOptions);
454  return true;
455 }
456 
458  return llvm::json::Object{{"token", P.token}};
459 }
460 
462  llvm::json::Object Result{
463  {"kind", "begin"},
464  {"title", P.title},
465  };
466  if (P.cancellable)
467  Result["cancellable"] = true;
468  if (P.percentage)
469  Result["percentage"] = 0;
470 
471  // FIXME: workaround for older gcc/clang
472  return std::move(Result);
473 }
474 
476  llvm::json::Object Result{{"kind", "report"}};
477  if (P.cancellable)
478  Result["cancellable"] = *P.cancellable;
479  if (P.message)
480  Result["message"] = *P.message;
481  if (P.percentage)
482  Result["percentage"] = *P.percentage;
483  // FIXME: workaround for older gcc/clang
484  return std::move(Result);
485 }
486 
488  llvm::json::Object Result{{"kind", "end"}};
489  if (P.message)
490  Result["message"] = *P.message;
491  // FIXME: workaround for older gcc/clang
492  return std::move(Result);
493 }
494 
496  return static_cast<int64_t>(R);
497 }
498 
500  return llvm::json::Object{{"type", R.type}, {"message", R.message}};
501 }
502 
504  llvm::json::Path P) {
505  llvm::json::ObjectMapper O(Params, P);
506  return O && O.map("textDocument", R.textDocument);
507 }
508 
510  llvm::json::Path P) {
511  llvm::json::ObjectMapper O(Params, P);
512  return O && O.map("textDocument", R.textDocument);
513 }
514 
516  llvm::json::Path P) {
517  llvm::json::ObjectMapper O(Params, P);
518  return O && O.map("textDocument", R.textDocument);
519 }
520 
522  llvm::json::Path P) {
523  llvm::json::ObjectMapper O(Params, P);
524  return O && O.map("textDocument", R.textDocument) &&
525  O.map("contentChanges", R.contentChanges) &&
526  O.map("wantDiagnostics", R.wantDiagnostics) &&
527  mapOptOrNull(Params, "forceRebuild", R.forceRebuild, P);
528 }
529 
531  llvm::json::Path P) {
532  if (auto T = E.getAsInteger()) {
533  if (*T < static_cast<int>(FileChangeType::Created) ||
534  *T > static_cast<int>(FileChangeType::Deleted))
535  return false;
536  Out = static_cast<FileChangeType>(*T);
537  return true;
538  }
539  return false;
540 }
541 
542 bool fromJSON(const llvm::json::Value &Params, FileEvent &R,
543  llvm::json::Path P) {
544  llvm::json::ObjectMapper O(Params, P);
545  return O && O.map("uri", R.uri) && O.map("type", R.type);
546 }
547 
549  llvm::json::Path P) {
550  llvm::json::ObjectMapper O(Params, P);
551  return O && O.map("changes", R.changes);
552 }
553 
554 bool fromJSON(const llvm::json::Value &Params,
556  llvm::json::ObjectMapper O(Params, P);
557  return O && O.map("range", R.range) && O.map("rangeLength", R.rangeLength) &&
558  O.map("text", R.text);
559 }
560 
562  llvm::json::Path P) {
563  llvm::json::ObjectMapper O(Params, P);
564  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
565 }
566 
567 bool fromJSON(const llvm::json::Value &Params,
569  llvm::json::ObjectMapper O(Params, P);
570  return O && O.map("textDocument", R.textDocument) &&
571  O.map("position", R.position) && O.map("ch", R.ch);
572 }
573 
575  llvm::json::Path P) {
576  llvm::json::ObjectMapper O(Params, P);
577  return O && O.map("textDocument", R.textDocument);
578 }
579 
581  llvm::json::Path P) {
582  llvm::json::ObjectMapper O(Params, P);
583  return O && O.map("textDocument", R.textDocument);
584 }
585 
587  return llvm::json::Object{
588  {"location", DRI.location},
589  {"message", DRI.message},
590  };
591 }
592 
593 llvm::json::Value toJSON(DiagnosticTag Tag) { return static_cast<int>(Tag); }
594 
596  return llvm::json::Object{{"href", D.href}};
597 }
598 
600  llvm::json::Object Diag{
601  {"range", D.range},
602  {"severity", D.severity},
603  {"message", D.message},
604  };
605  if (D.category)
606  Diag["category"] = *D.category;
607  if (D.codeActions)
608  Diag["codeActions"] = D.codeActions;
609  if (!D.code.empty())
610  Diag["code"] = D.code;
611  if (D.codeDescription.hasValue())
612  Diag["codeDescription"] = *D.codeDescription;
613  if (!D.source.empty())
614  Diag["source"] = D.source;
615  if (D.relatedInformation)
616  Diag["relatedInformation"] = *D.relatedInformation;
617  if (!D.data.empty())
618  Diag["data"] = llvm::json::Object(D.data);
619  if (!D.tags.empty())
620  Diag["tags"] = llvm::json::Array{D.tags};
621  // FIXME: workaround for older gcc/clang
622  return std::move(Diag);
623 }
624 
625 bool fromJSON(const llvm::json::Value &Params, Diagnostic &R,
626  llvm::json::Path P) {
627  llvm::json::ObjectMapper O(Params, P);
628  if (!O)
629  return false;
630  if (auto *Data = Params.getAsObject()->getObject("data"))
631  R.data = *Data;
632  return O.map("range", R.range) && O.map("message", R.message) &&
633  mapOptOrNull(Params, "severity", R.severity, P) &&
634  mapOptOrNull(Params, "category", R.category, P) &&
635  mapOptOrNull(Params, "code", R.code, P) &&
636  mapOptOrNull(Params, "source", R.source, P);
637 }
638 
640  llvm::json::Object Result{
641  {"uri", PDP.uri},
642  {"diagnostics", PDP.diagnostics},
643  };
644  if (PDP.version)
645  Result["version"] = PDP.version;
646  return std::move(Result);
647 }
648 
650  llvm::json::Path P) {
651  llvm::json::ObjectMapper O(Params, P);
652  if (!O || !O.map("diagnostics", R.diagnostics))
653  return false;
654  O.map("only", R.only);
655  return true;
656 }
657 
658 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Diagnostic &D) {
659  OS << D.range << " [";
660  switch (D.severity) {
661  case 1:
662  OS << "error";
663  break;
664  case 2:
665  OS << "warning";
666  break;
667  case 3:
668  OS << "note";
669  break;
670  case 4:
671  OS << "remark";
672  break;
673  default:
674  OS << "diagnostic";
675  break;
676  }
677  return OS << '(' << D.severity << "): " << D.message << "]";
678 }
679 
681  llvm::json::Path P) {
682  llvm::json::ObjectMapper O(Params, P);
683  return O && O.map("textDocument", R.textDocument) &&
684  O.map("range", R.range) && O.map("context", R.context);
685 }
686 
687 bool fromJSON(const llvm::json::Value &Params, WorkspaceEdit &R,
688  llvm::json::Path P) {
689  llvm::json::ObjectMapper O(Params, P);
690  return O && O.map("changes", R.changes);
691 }
692 
694  llvm::json::Path P) {
695  llvm::json::ObjectMapper O(Params, P);
696  if (!O || !O.map("command", R.command))
697  return false;
698 
699  const auto *Args = Params.getAsObject()->get("arguments");
700  if (!Args)
701  return true; // Missing args is ok, argument is null.
702  const auto *ArgsArray = Args->getAsArray();
703  if (!ArgsArray) {
704  P.field("arguments").report("expected array");
705  return false;
706  }
707  if (ArgsArray->size() > 1) {
708  P.field("arguments").report("Command should have 0 or 1 argument");
709  return false;
710  }
711  if (ArgsArray->size() == 1) {
712  R.argument = ArgsArray->front();
713  }
714  return true;
715 }
716 
718  llvm::json::Object O{
719  {"name", P.name},
720  {"kind", static_cast<int>(P.kind)},
721  {"location", P.location},
722  {"containerName", P.containerName},
723  };
724  if (P.score)
725  O["score"] = *P.score;
726  return std::move(O);
727 }
728 
729 llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
730  const SymbolInformation &SI) {
731  O << SI.containerName << "::" << SI.name << " - " << toJSON(SI);
732  return O;
733 }
734 
735 bool operator==(const SymbolDetails &LHS, const SymbolDetails &RHS) {
736  return LHS.name == RHS.name && LHS.containerName == RHS.containerName &&
737  LHS.USR == RHS.USR && LHS.ID == RHS.ID;
738 }
739 
741  llvm::json::Object Result{{"name", llvm::json::Value(nullptr)},
742  {"containerName", llvm::json::Value(nullptr)},
743  {"usr", llvm::json::Value(nullptr)},
744  {"id", llvm::json::Value(nullptr)}};
745 
746  if (!P.name.empty())
747  Result["name"] = P.name;
748 
749  if (!P.containerName.empty())
750  Result["containerName"] = P.containerName;
751 
752  if (!P.USR.empty())
753  Result["usr"] = P.USR;
754 
755  if (P.ID)
756  Result["id"] = P.ID.str();
757 
758  // FIXME: workaround for older gcc/clang
759  return std::move(Result);
760 }
761 
762 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) {
763  if (!S.containerName.empty()) {
764  O << S.containerName;
765  llvm::StringRef ContNameRef;
766  if (!ContNameRef.endswith("::")) {
767  O << " ";
768  }
769  }
770  O << S.name << " - " << toJSON(S);
771  return O;
772 }
773 
775  llvm::json::Path P) {
776  llvm::json::ObjectMapper O(Params, P);
777  return O && O.map("query", R.query) &&
778  mapOptOrNull(Params, "limit", R.limit, P);
779 }
780 
781 llvm::json::Value toJSON(const Command &C) {
782  auto Cmd = llvm::json::Object{{"title", C.title}, {"command", C.command}};
783  if (!C.argument.getAsNull())
784  Cmd["arguments"] = llvm::json::Array{C.argument};
785  return std::move(Cmd);
786 }
787 
788 const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix";
789 const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor";
790 const llvm::StringLiteral CodeAction::INFO_KIND = "info";
791 
793  auto CodeAction = llvm::json::Object{{"title", CA.title}};
794  if (CA.kind)
795  CodeAction["kind"] = *CA.kind;
796  if (CA.diagnostics)
797  CodeAction["diagnostics"] = llvm::json::Array(*CA.diagnostics);
798  if (CA.isPreferred)
799  CodeAction["isPreferred"] = true;
800  if (CA.edit)
801  CodeAction["edit"] = *CA.edit;
802  if (CA.command)
803  CodeAction["command"] = *CA.command;
804  return std::move(CodeAction);
805 }
806 
807 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentSymbol &S) {
808  return O << S.name << " - " << toJSON(S);
809 }
810 
812  llvm::json::Object Result{{"name", S.name},
813  {"kind", static_cast<int>(S.kind)},
814  {"range", S.range},
815  {"selectionRange", S.selectionRange}};
816 
817  if (!S.detail.empty())
818  Result["detail"] = S.detail;
819  if (!S.children.empty())
820  Result["children"] = S.children;
821  if (S.deprecated)
822  Result["deprecated"] = true;
823  // FIXME: workaround for older gcc/clang
824  return std::move(Result);
825 }
826 
828  llvm::json::Object FileChanges;
829  for (auto &Change : WE.changes)
830  FileChanges[Change.first] = llvm::json::Array(Change.second);
831  return llvm::json::Object{{"changes", std::move(FileChanges)}};
832 }
833 
834 bool fromJSON(const llvm::json::Value &Params, TweakArgs &A,
835  llvm::json::Path P) {
836  llvm::json::ObjectMapper O(Params, P);
837  return O && O.map("file", A.file) && O.map("selection", A.selection) &&
838  O.map("tweakID", A.tweakID);
839 }
840 
842  return llvm::json::Object{
843  {"tweakID", A.tweakID}, {"selection", A.selection}, {"file", A.file}};
844 }
845 
847  return llvm::json::Object{{"edit", Params.edit}};
848 }
849 
851  llvm::json::Path P) {
852  llvm::json::ObjectMapper O(Response, P);
853  return O && O.map("applied", R.applied) &&
854  O.map("failureReason", R.failureReason);
855 }
856 
858  llvm::json::Path P) {
859  llvm::json::ObjectMapper O(Params, P);
860  return O && O.map("textDocument", R.textDocument) &&
861  O.map("position", R.position);
862 }
863 
865  llvm::json::Path P) {
866  llvm::json::ObjectMapper O(Params, P);
867  int TriggerKind;
868  if (!O || !O.map("triggerKind", TriggerKind) ||
869  !mapOptOrNull(Params, "triggerCharacter", R.triggerCharacter, P))
870  return false;
871  R.triggerKind = static_cast<CompletionTriggerKind>(TriggerKind);
872  return true;
873 }
874 
876  llvm::json::Path P) {
877  if (!fromJSON(Params, static_cast<TextDocumentPositionParams &>(R), P) ||
878  !mapOptOrNull(Params, "limit", R.limit, P))
879  return false;
880  if (auto *Context = Params.getAsObject()->get("context"))
881  return fromJSON(*Context, R.context, P.field("context"));
882  return true;
883 }
884 
885 static llvm::StringRef toTextKind(MarkupKind Kind) {
886  switch (Kind) {
888  return "plaintext";
890  return "markdown";
891  }
892  llvm_unreachable("Invalid MarkupKind");
893 }
894 
896  auto Str = V.getAsString();
897  if (!Str) {
898  P.report("expected string");
899  return false;
900  }
901  if (*Str == "plaintext")
903  else if (*Str == "markdown")
905  else {
906  P.report("unknown markup kind");
907  return false;
908  }
909  return true;
910 }
911 
912 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, MarkupKind K) {
913  return OS << toTextKind(K);
914 }
915 
917  if (MC.value.empty())
918  return nullptr;
919 
920  return llvm::json::Object{
921  {"kind", toTextKind(MC.kind)},
922  {"value", MC.value},
923  };
924 }
925 
927  llvm::json::Object Result{{"contents", toJSON(H.contents)}};
928 
929  if (H.range.hasValue())
930  Result["range"] = toJSON(*H.range);
931 
932  return std::move(Result);
933 }
934 
936  llvm::json::Path P) {
937  if (auto T = E.getAsInteger()) {
938  if (*T < static_cast<int>(CompletionItemKind::Text) ||
939  *T > static_cast<int>(CompletionItemKind::TypeParameter))
940  return false;
941  Out = static_cast<CompletionItemKind>(*T);
942  return true;
943  }
944  return false;
945 }
946 
949  CompletionItemKindBitset &SupportedCompletionItemKinds) {
950  auto KindVal = static_cast<size_t>(Kind);
951  if (KindVal >= CompletionItemKindMin &&
952  KindVal <= SupportedCompletionItemKinds.size() &&
953  SupportedCompletionItemKinds[KindVal])
954  return Kind;
955 
956  switch (Kind) {
957  // Provide some fall backs for common kinds that are close enough.
964  default:
966  }
967 }
968 
970  llvm::json::Path P) {
971  if (auto *A = E.getAsArray()) {
972  for (size_t I = 0; I < A->size(); ++I) {
973  CompletionItemKind KindOut;
974  if (fromJSON((*A)[I], KindOut, P.index(I)))
975  Out.set(size_t(KindOut));
976  }
977  return true;
978  }
979  return false;
980 }
981 
983  assert(!CI.label.empty() && "completion item label is required");
984  llvm::json::Object Result{{"label", CI.label}};
985  if (CI.kind != CompletionItemKind::Missing)
986  Result["kind"] = static_cast<int>(CI.kind);
987  if (!CI.detail.empty())
988  Result["detail"] = CI.detail;
989  if (CI.documentation)
990  Result["documentation"] = CI.documentation;
991  if (!CI.sortText.empty())
992  Result["sortText"] = CI.sortText;
993  if (!CI.filterText.empty())
994  Result["filterText"] = CI.filterText;
995  if (!CI.insertText.empty())
996  Result["insertText"] = CI.insertText;
997  if (CI.insertTextFormat != InsertTextFormat::Missing)
998  Result["insertTextFormat"] = static_cast<int>(CI.insertTextFormat);
999  if (CI.textEdit)
1000  Result["textEdit"] = *CI.textEdit;
1001  if (!CI.additionalTextEdits.empty())
1002  Result["additionalTextEdits"] = llvm::json::Array(CI.additionalTextEdits);
1003  if (CI.deprecated)
1004  Result["deprecated"] = CI.deprecated;
1005  Result["score"] = CI.score;
1006  return std::move(Result);
1007 }
1008 
1009 llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const CompletionItem &I) {
1010  O << I.label << " - " << toJSON(I);
1011  return O;
1012 }
1013 
1014 bool operator<(const CompletionItem &L, const CompletionItem &R) {
1015  return (L.sortText.empty() ? L.label : L.sortText) <
1016  (R.sortText.empty() ? R.label : R.sortText);
1017 }
1018 
1020  return llvm::json::Object{
1021  {"isIncomplete", L.isIncomplete},
1022  {"items", llvm::json::Array(L.items)},
1023  };
1024 }
1025 
1027  assert((PI.labelOffsets.hasValue() || !PI.labelString.empty()) &&
1028  "parameter information label is required");
1029  llvm::json::Object Result;
1030  if (PI.labelOffsets)
1031  Result["label"] =
1032  llvm::json::Array({PI.labelOffsets->first, PI.labelOffsets->second});
1033  else
1034  Result["label"] = PI.labelString;
1035  if (!PI.documentation.empty())
1036  Result["documentation"] = PI.documentation;
1037  return std::move(Result);
1038 }
1039 
1041  assert(!SI.label.empty() && "signature information label is required");
1042  llvm::json::Object Result{
1043  {"label", SI.label},
1044  {"parameters", llvm::json::Array(SI.parameters)},
1045  };
1046  if (!SI.documentation.value.empty())
1047  Result["documentation"] = SI.documentation;
1048  return std::move(Result);
1049 }
1050 
1051 llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
1052  const SignatureInformation &I) {
1053  O << I.label << " - " << toJSON(I);
1054  return O;
1055 }
1056 
1058  assert(SH.activeSignature >= 0 &&
1059  "Unexpected negative value for number of active signatures.");
1060  assert(SH.activeParameter >= 0 &&
1061  "Unexpected negative value for active parameter index");
1062  return llvm::json::Object{
1063  {"activeSignature", SH.activeSignature},
1064  {"activeParameter", SH.activeParameter},
1065  {"signatures", llvm::json::Array(SH.signatures)},
1066  };
1067 }
1068 
1069 bool fromJSON(const llvm::json::Value &Params, RenameParams &R,
1070  llvm::json::Path P) {
1071  llvm::json::ObjectMapper O(Params, P);
1072  return O && O.map("textDocument", R.textDocument) &&
1073  O.map("position", R.position) && O.map("newName", R.newName);
1074 }
1075 
1077  return llvm::json::Object{
1078  {"range", toJSON(DH.range)},
1079  {"kind", static_cast<int>(DH.kind)},
1080  };
1081 }
1082 
1084  return llvm::json::Object{
1085  {"uri", FStatus.uri},
1086  {"state", FStatus.state},
1087  };
1088 }
1089 
1090 constexpr unsigned SemanticTokenEncodingSize = 5;
1091 static llvm::json::Value encodeTokens(llvm::ArrayRef<SemanticToken> Toks) {
1092  llvm::json::Array Result;
1093  Result.reserve(SemanticTokenEncodingSize * Toks.size());
1094  for (const auto &Tok : Toks) {
1095  Result.push_back(Tok.deltaLine);
1096  Result.push_back(Tok.deltaStart);
1097  Result.push_back(Tok.length);
1098  Result.push_back(Tok.tokenType);
1099  Result.push_back(Tok.tokenModifiers);
1100  }
1101  assert(Result.size() == SemanticTokenEncodingSize * Toks.size());
1102  return std::move(Result);
1103 }
1104 
1105 bool operator==(const SemanticToken &L, const SemanticToken &R) {
1106  return std::tie(L.deltaLine, L.deltaStart, L.length, L.tokenType,
1107  L.tokenModifiers) == std::tie(R.deltaLine, R.deltaStart,
1108  R.length, R.tokenType,
1109  R.tokenModifiers);
1110 }
1111 
1113  return llvm::json::Object{{"resultId", Tokens.resultId},
1114  {"data", encodeTokens(Tokens.tokens)}};
1115 }
1116 
1118  return llvm::json::Object{
1119  {"start", SemanticTokenEncodingSize * Edit.startToken},
1120  {"deleteCount", SemanticTokenEncodingSize * Edit.deleteTokens},
1121  {"data", encodeTokens(Edit.tokens)}};
1122 }
1123 
1125  llvm::json::Object Result{{"resultId", TE.resultId}};
1126  if (TE.edits)
1127  Result["edits"] = *TE.edits;
1128  if (TE.tokens)
1129  Result["data"] = encodeTokens(*TE.tokens);
1130  return std::move(Result);
1131 }
1132 
1134  llvm::json::Path P) {
1135  llvm::json::ObjectMapper O(Params, P);
1136  return O && O.map("textDocument", R.textDocument);
1137 }
1138 
1140  llvm::json::Path P) {
1141  llvm::json::ObjectMapper O(Params, P);
1142  return O && O.map("textDocument", R.textDocument) &&
1143  O.map("previousResultId", R.previousResultId);
1144 }
1145 
1146 llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
1147  const DocumentHighlight &V) {
1148  O << V.range;
1150  O << "(r)";
1152  O << "(w)";
1153  return O;
1154 }
1155 
1156 bool fromJSON(const llvm::json::Value &Params,
1158  llvm::json::ObjectMapper O(Params, P);
1159  return O && O.map("settings", CCP.settings);
1160 }
1161 
1162 bool fromJSON(const llvm::json::Value &Params, ClangdCompileCommand &CDbUpdate,
1163  llvm::json::Path P) {
1164  llvm::json::ObjectMapper O(Params, P);
1165  return O && O.map("workingDirectory", CDbUpdate.workingDirectory) &&
1166  O.map("compilationCommand", CDbUpdate.compilationCommand);
1167 }
1168 
1170  llvm::json::Path P) {
1171  llvm::json::ObjectMapper O(Params, P);
1172  if (!O)
1173  return true; // 'any' type in LSP.
1174  return mapOptOrNull(Params, "compilationDatabaseChanges",
1176 }
1177 
1179  llvm::json::Path P) {
1180  llvm::json::ObjectMapper O(Params, P);
1181  if (!O)
1182  return true; // 'any' type in LSP.
1183 
1184  return fromJSON(Params, Opts.ConfigSettings, P) &&
1185  O.map("compilationDatabasePath", Opts.compilationDatabasePath) &&
1186  mapOptOrNull(Params, "fallbackFlags", Opts.fallbackFlags, P) &&
1187  mapOptOrNull(Params, "clangdFileStatus", Opts.FileStatus, P);
1188 }
1189 
1191  llvm::json::Path P) {
1192  auto T = E.getAsInteger();
1193  if (!T)
1194  return false;
1195  if (*T < static_cast<int>(TypeHierarchyDirection::Children) ||
1196  *T > static_cast<int>(TypeHierarchyDirection::Both))
1197  return false;
1198  Out = static_cast<TypeHierarchyDirection>(*T);
1199  return true;
1200 }
1201 
1203  llvm::json::Path P) {
1204  llvm::json::ObjectMapper O(Params, P);
1205  return O && O.map("textDocument", R.textDocument) &&
1206  O.map("position", R.position) && O.map("resolve", R.resolve) &&
1207  O.map("direction", R.direction);
1208 }
1209 
1210 llvm::raw_ostream &operator<<(llvm::raw_ostream &O,
1211  const TypeHierarchyItem &I) {
1212  return O << I.name << " - " << toJSON(I);
1213 }
1214 
1216  llvm::json::Object Result{{"name", I.name},
1217  {"kind", static_cast<int>(I.kind)},
1218  {"range", I.range},
1219  {"selectionRange", I.selectionRange},
1220  {"uri", I.uri}};
1221 
1222  if (I.detail)
1223  Result["detail"] = I.detail;
1224  if (I.deprecated)
1225  Result["deprecated"] = I.deprecated;
1226  if (I.parents)
1227  Result["parents"] = I.parents;
1228  if (I.children)
1229  Result["children"] = I.children;
1230  if (I.data)
1231  Result["data"] = I.data;
1232  return std::move(Result);
1233 }
1234 
1236  llvm::json::Path P) {
1237  llvm::json::ObjectMapper O(Params, P);
1238 
1239  // Required fields.
1240  return O && O.map("name", I.name) && O.map("kind", I.kind) &&
1241  O.map("uri", I.uri) && O.map("range", I.range) &&
1242  O.map("selectionRange", I.selectionRange) &&
1243  mapOptOrNull(Params, "detail", I.detail, P) &&
1244  mapOptOrNull(Params, "deprecated", I.deprecated, P) &&
1245  mapOptOrNull(Params, "parents", I.parents, P) &&
1246  mapOptOrNull(Params, "children", I.children, P) &&
1247  mapOptOrNull(Params, "data", I.data, P);
1248 }
1249 
1250 bool fromJSON(const llvm::json::Value &Params,
1252  llvm::json::ObjectMapper O(Params, P);
1253  return O && O.map("item", R.item) && O.map("resolve", R.resolve) &&
1254  O.map("direction", R.direction);
1255 }
1256 
1258  llvm::json::Path P) {
1259  llvm::json::ObjectMapper O(Params, P);
1260  return O && O.mapOptional("includeDeclaration", R.includeDeclaration);
1261 }
1262 
1264  llvm::json::Path P) {
1266  llvm::json::ObjectMapper O(Params, P);
1267  return fromJSON(Params, Base, P) && O && O.mapOptional("context", R.context);
1268 }
1269 
1271  return llvm::json::Value{static_cast<int>(Tag)};
1272 }
1273 
1275  llvm::json::Object Result{{"name", I.name},
1276  {"kind", static_cast<int>(I.kind)},
1277  {"range", I.range},
1278  {"selectionRange", I.selectionRange},
1279  {"uri", I.uri}};
1280  if (!I.tags.empty())
1281  Result["tags"] = I.tags;
1282  if (!I.detail.empty())
1283  Result["detail"] = I.detail;
1284  if (!I.data.empty())
1285  Result["data"] = I.data;
1286  return std::move(Result);
1287 }
1288 
1290  llvm::json::Path P) {
1291  llvm::json::ObjectMapper O(Params, P);
1292 
1293  // Populate the required fields only. We don't care about the
1294  // optional fields `Tags` and `Detail` for the purpose of
1295  // client --> server communication.
1296  return O && O.map("name", I.name) && O.map("kind", I.kind) &&
1297  O.map("uri", I.uri) && O.map("range", I.range) &&
1298  O.map("selectionRange", I.selectionRange) &&
1299  mapOptOrNull(Params, "data", I.data, P);
1300 }
1301 
1302 bool fromJSON(const llvm::json::Value &Params,
1304  llvm::json::ObjectMapper O(Params, P);
1305  return O.map("item", C.item);
1306 }
1307 
1309  return llvm::json::Object{{"from", C.from}, {"fromRanges", C.fromRanges}};
1310 }
1311 
1312 bool fromJSON(const llvm::json::Value &Params,
1314  llvm::json::ObjectMapper O(Params, P);
1315  return O.map("item", C.item);
1316 }
1317 
1319  return llvm::json::Object{{"to", C.to}, {"fromRanges", C.fromRanges}};
1320 }
1321 
1323  llvm::json::Path P) {
1324  llvm::json::ObjectMapper O(Params, P);
1325  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
1326 }
1327 
1329  switch (Kind) {
1330  case InlayHintKind::Type:
1331  return 1;
1333  return 2;
1334  case InlayHintKind::Designator: // This is an extension, don't serialize.
1335  return nullptr;
1336  }
1337  llvm_unreachable("Unknown clang.clangd.InlayHintKind");
1338 }
1339 
1341  llvm::json::Object Result{{"position", H.position},
1342  {"label", H.label},
1343  {"paddingLeft", H.paddingLeft},
1344  {"paddingRight", H.paddingRight}};
1345  auto K = toJSON(H.kind);
1346  if (!K.getAsNull())
1347  Result["kind"] = std::move(K);
1348  return std::move(Result);
1349 }
1350 bool operator==(const InlayHint &A, const InlayHint &B) {
1351  return std::tie(A.position, A.range, A.kind, A.label) ==
1352  std::tie(B.position, B.range, B.kind, B.label);
1353 }
1354 bool operator<(const InlayHint &A, const InlayHint &B) {
1355  return std::tie(A.position, A.range, A.kind, A.label) <
1356  std::tie(B.position, B.range, B.kind, B.label);
1357 }
1358 
1359 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, InlayHintKind Kind) {
1360  auto ToString = [](InlayHintKind K) {
1361  switch (K) {
1363  return "parameter";
1364  case InlayHintKind::Type:
1365  return "type";
1367  return "designator";
1368  }
1369  llvm_unreachable("Unknown clang.clangd.InlayHintKind");
1370  };
1371  return OS << ToString(Kind);
1372 }
1373 
1374 static const char *toString(OffsetEncoding OE) {
1375  switch (OE) {
1376  case OffsetEncoding::UTF8:
1377  return "utf-8";
1378  case OffsetEncoding::UTF16:
1379  return "utf-16";
1380  case OffsetEncoding::UTF32:
1381  return "utf-32";
1383  return "unknown";
1384  }
1385  llvm_unreachable("Unknown clang.clangd.OffsetEncoding");
1386 }
1389  llvm::json::Path P) {
1390  auto Str = V.getAsString();
1391  if (!Str)
1392  return false;
1393  OE = llvm::StringSwitch<OffsetEncoding>(*Str)
1394  .Case("utf-8", OffsetEncoding::UTF8)
1395  .Case("utf-16", OffsetEncoding::UTF16)
1396  .Case("utf-32", OffsetEncoding::UTF32)
1398  return true;
1399 }
1400 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OffsetEncoding Enc) {
1401  return OS << toString(Enc);
1402 }
1403 
1405  llvm::json::Path P) {
1406  llvm::json::ObjectMapper O(Params, P);
1407  return O && O.map("textDocument", S.textDocument) &&
1408  O.map("positions", S.positions);
1409 }
1410 
1412  if (Out.parent) {
1413  return llvm::json::Object{{"range", Out.range},
1414  {"parent", toJSON(*Out.parent)}};
1415  }
1416  return llvm::json::Object{{"range", Out.range}};
1417 }
1418 
1420  llvm::json::Path P) {
1421  llvm::json::ObjectMapper O(Params, P);
1422  return O && O.map("textDocument", R.textDocument);
1423 }
1424 
1426  return llvm::json::Object{
1427  {"range", DocumentLink.range},
1428  {"target", DocumentLink.target},
1429  };
1430 }
1431 
1433  llvm::json::Path P) {
1434  llvm::json::ObjectMapper O(Params, P);
1435  return O && O.map("textDocument", R.textDocument);
1436 }
1437 
1439  llvm::json::Object Result{
1440  {"startLine", Range.startLine},
1441  {"endLine", Range.endLine},
1442  };
1443  if (Range.startCharacter)
1444  Result["startCharacter"] = Range.startCharacter;
1445  if (Range.endCharacter)
1446  Result["endCharacter"] = Range.endCharacter;
1447  if (Range.kind)
1448  Result["kind"] = *Range.kind;
1449  return Result;
1450 }
1451 
1453  llvm::json::Object Out;
1454  int64_t Total = MT.self();
1455  Out["_self"] = Total;
1456  for (const auto &Entry : MT.children()) {
1457  auto Child = toJSON(Entry.getSecond());
1458  Total += *Child.getAsObject()->getInteger("_total");
1459  Out[Entry.first] = std::move(Child);
1460  }
1461  Out["_total"] = Total;
1462  return Out;
1463 }
1464 
1465 bool fromJSON(const llvm::json::Value &Params, ASTParams &R,
1466  llvm::json::Path P) {
1467  llvm::json::ObjectMapper O(Params, P);
1468  return O && O.map("textDocument", R.textDocument) && O.map("range", R.range);
1469 }
1470 
1472  llvm::json::Object Result{
1473  {"role", N.role},
1474  {"kind", N.kind},
1475  };
1476  if (!N.children.empty())
1477  Result["children"] = N.children;
1478  if (!N.detail.empty())
1479  Result["detail"] = N.detail;
1480  if (!N.arcana.empty())
1481  Result["arcana"] = N.arcana;
1482  if (N.range)
1483  Result["range"] = *N.range;
1484  return Result;
1485 }
1486 
1487 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ASTNode &Root) {
1488  std::function<void(const ASTNode &, unsigned)> Print = [&](const ASTNode &N,
1489  unsigned Level) {
1490  OS.indent(2 * Level) << N.role << ": " << N.kind;
1491  if (!N.detail.empty())
1492  OS << " - " << N.detail;
1493  OS << "\n";
1494  for (const ASTNode &C : N.children)
1495  Print(C, Level + 1);
1496  };
1497  Print(Root, 0);
1498  return OS;
1499 }
1500 
1501 } // namespace clangd
1502 } // namespace clang
clang::clangd::TraceLevel::Messages
@ Messages
clang::clangd::ReferenceContext::includeDeclaration
bool includeDeclaration
Include the declaration of the current symbol.
Definition: Protocol.h:1612
clang::clangd::CallHierarchyItem::selectionRange
Range selectionRange
The range that should be selected and revealed when this symbol is being picked, e....
Definition: Protocol.h:1479
clang::clangd::DocumentHighlight
A document highlight is a range inside a text document which deserves special attention.
Definition: Protocol.h:1349
Total
unsigned Total
Definition: FunctionCognitiveComplexityCheck.cpp:145
clang::clangd::TypeHierarchyItem::selectionRange
Range selectionRange
The range that should be selected and revealed when this type hierarchy item is being picked,...
Definition: Protocol.h:1414
clang::clangd::WorkspaceEdit
Definition: Protocol.h:946
clang::clangd::DocumentSymbol::range
Range range
The range enclosing this symbol not including leading/trailing whitespace but everything else like co...
Definition: Protocol.h:1043
clang::clangd::InlayHintKind::Designator
@ Designator
A hint before an element of an aggregate braced initializer list, indicating what it is initializing.
clang::clangd::SymbolKind::Field
@ Field
clang::clangd::DidOpenTextDocumentParams::textDocument
TextDocumentItem textDocument
The document that was opened.
Definition: Protocol.h:681
Base
std::unique_ptr< GlobalCompilationDatabase > Base
Definition: GlobalCompilationDatabaseTests.cpp:85
clang::clangd::Diagnostic::source
std::string source
A human-readable string describing the source of this diagnostic, e.g.
Definition: Protocol.h:862
clang::clangd::DocumentOnTypeFormattingParams::ch
std::string ch
The character that has been typed.
Definition: Protocol.h:795
clang::clangd::SymbolKindMin
constexpr auto SymbolKindMin
Definition: Protocol.h:362
clang::clangd::TextDocumentIdentifier::uri
URIForFile uri
The text document's URI.
Definition: Protocol.h:130
clang::clangd::ClangdCompileCommand
Clangd extension that's used in the 'compilationDatabaseChanges' in workspace/didChangeConfiguration ...
Definition: Protocol.h:503
clang::clangd::ReferenceContext
Definition: Protocol.h:1610
clang::clangd::ClangdCompileCommand::workingDirectory
std::string workingDirectory
Definition: Protocol.h:504
clang::clangd::MarkupKind::PlainText
@ PlainText
clang::clangd::ClientCapabilities::DiagnosticFixes
bool DiagnosticFixes
Whether the client accepts diagnostics with codeActions attached inline.
Definition: Protocol.h:409
clang::clangd::MarkupKind::Markdown
@ Markdown
clang::clangd::DidChangeTextDocumentParams::wantDiagnostics
llvm::Optional< bool > wantDiagnostics
Forces diagnostics to be generated, or to not be generated, for this version of the file.
Definition: Protocol.h:726
clang::clangd::SemanticTokensDeltaParams::previousResultId
std::string previousResultId
The previous result id.
Definition: Protocol.h:1677
clang::clangd::SemanticToken::tokenModifiers
unsigned tokenModifiers
each set bit will be looked up in SemanticTokensLegend.tokenModifiers
Definition: Protocol.h:1646
clang::clangd::Edit
A set of edits generated for a single file.
Definition: SourceCode.h:184
clang::clangd::SemanticTokensParams
Body of textDocument/semanticTokens/full request.
Definition: Protocol.h:1664
E
const Expr * E
Definition: AvoidBindCheck.cpp:88
clang::clangd::Location::uri
URIForFile uri
The text document's URI.
Definition: Protocol.h:210
clang::clangd::SymbolTag
SymbolTag
Definition: Protocol.h:1448
clang::clangd::PublishDiagnosticsParams::diagnostics
std::vector< Diagnostic > diagnostics
An array of diagnostic information items.
Definition: Protocol.h:911
clang::clangd::FileEvent::uri
URIForFile uri
The file's URI.
Definition: Protocol.h:750
clang::clangd::TraceLevel
TraceLevel
Definition: Protocol.h:262
clang::clangd::ClientCapabilities::DiagnosticCategory
bool DiagnosticCategory
Whether the client accepts diagnostics with category attached to it using the "category" extension.
Definition: Protocol.h:418
clang::clangd::SemanticTokensOrDelta::resultId
std::string resultId
Definition: Protocol.h:1696
clang::clangd::CompletionItemKind::Class
@ Class
clang::clangd::FileEvent
Definition: Protocol.h:748
clang::clangd::CallHierarchyItem::uri
URIForFile uri
The resource identifier of this item.
Definition: Protocol.h:1470
clang::clangd::ShowMessageParams::type
MessageType type
The message type.
Definition: Protocol.h:673
clang::clangd::ResolveTypeHierarchyItemParams::resolve
int resolve
The hierarchy levels to resolve. 0 indicates no level.
Definition: Protocol.h:1440
clang::clangd::SemanticTokensParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1666
clang::clangd::CallHierarchyItem::detail
std::string detail
More detaill for this item, e.g. the signature of a function.
Definition: Protocol.h:1467
clang::clangd::CodeAction
A code action represents a change that can be performed in code, e.g.
Definition: Protocol.h:992
clang::clangd::Diagnostic::category
llvm::Optional< std::string > category
The diagnostic's category.
Definition: Protocol.h:878
clang::clangd::SemanticTokensDeltaParams
Body of textDocument/semanticTokens/full/delta request.
Definition: Protocol.h:1673
clang::clangd::MarkupContent::kind
MarkupKind kind
Definition: Protocol.h:1166
clang::clangd::Location
Definition: Protocol.h:208
clang::clangd::ClientCapabilities::CompletionItemKinds
llvm::Optional< CompletionItemKindBitset > CompletionItemKinds
The supported set of CompletionItemKinds for textDocument/completion.
Definition: Protocol.h:448
clang::clangd::SemanticTokenEncodingSize
constexpr unsigned SemanticTokenEncodingSize
Definition: Protocol.cpp:1090
clang::clangd::DocumentOnTypeFormattingParams::textDocument
TextDocumentIdentifier textDocument
The document to format.
Definition: Protocol.h:789
clang::clangd::WorkDoneProgressEnd::message
llvm::Optional< std::string > message
Optional, a final message indicating to for example indicate the outcome of the operation.
Definition: Protocol.h:653
clang::clangd::DocumentRangeFormattingParams::textDocument
TextDocumentIdentifier textDocument
The document to format.
Definition: Protocol.h:779
clang::clangd::InitializeParams::processId
llvm::Optional< int > processId
The process Id of the parent process that started the server.
Definition: Protocol.h:545
clang::clangd::ASTNode::detail
std::string detail
Brief additional information, such as "||" for the particular operator.
Definition: Protocol.h:1825
clang::clangd::CompletionList
Represents a collection of completion items to be presented in the editor.
Definition: Protocol.h:1267
clang::clangd::ClientCapabilities::CompletionFixes
bool CompletionFixes
Client supports completions with additionalTextEdit near the cursor.
Definition: Protocol.h:427
Diagnostics
WantDiagnostics Diagnostics
Definition: TUScheduler.cpp:602
clang::clangd::Context::get
const Type * get(const Key< Type > &Key) const
Get data stored for a typed Key.
Definition: Context.h:98
clang::clangd::CodeActionContext::only
std::vector< std::string > only
Requested kind of actions to return.
Definition: Protocol.h:930
clang::clangd::DiagnosticTag
DiagnosticTag
Definition: Protocol.h:825
clang::clangd::ClientCapabilities
Definition: Protocol.h:402
clang::clangd::SemanticTokensEdit
Describes a a replacement of a contiguous range of semanticTokens.
Definition: Protocol.h:1683
clang::clangd::SemanticTokensOrDelta
This models LSP SemanticTokensDelta | SemanticTokens, which is the result of textDocument/semanticTok...
Definition: Protocol.h:1695
clang::clangd::DocumentRangeFormattingParams::range
Range range
The range to format.
Definition: Protocol.h:782
clang::clangd::Hover
Definition: Protocol.h:1171
clang::clangd::ClientCapabilities::WorkspaceSymbolKinds
llvm::Optional< SymbolKindBitset > WorkspaceSymbolKinds
The supported set of SymbolKinds for workspace/symbol.
Definition: Protocol.h:405
clang::clangd::SelectionRangeParams::positions
std::vector< Position > positions
The positions inside the text document.
Definition: Protocol.h:1709
clang::clangd::DidCloseTextDocumentParams
Definition: Protocol.h:686
clang::clangd::DocumentOnTypeFormattingParams::position
Position position
The position at which this request was sent.
Definition: Protocol.h:792
clang::clangd::SignatureInformation::documentation
MarkupContent documentation
The documentation of this signature. Optional.
Definition: Protocol.h:1301
CI
std::unique_ptr< CompilerInvocation > CI
Definition: TUScheduler.cpp:491
clang::clangd::CodeAction::isPreferred
bool isPreferred
Marks this as a preferred action.
Definition: Protocol.h:1011
clang::clangd::ApplyWorkspaceEditResponse::applied
bool applied
Definition: Protocol.h:1120
clang::clangd::OffsetEncoding::UTF32
@ UTF32
Root
ASTNode Root
Definition: DumpAST.cpp:332
clang::clangd::SymbolInformation
Represents information about programming constructs like variables, classes, interfaces etc.
Definition: Protocol.h:1057
clang::clangd::DidChangeConfigurationParams::settings
ConfigurationSettings settings
Definition: Protocol.h:764
Kind
BindArgumentKind Kind
Definition: AvoidBindCheck.cpp:59
clang::clangd::CompletionItem::label
std::string label
The label of this completion item.
Definition: Protocol.h:1202
clang::clangd::ClientCapabilities::HierarchicalDocumentSymbol
bool HierarchicalDocumentSymbol
Client supports hierarchical document symbols.
Definition: Protocol.h:431
clang::clangd::Range::start
Position start
The range's start position.
Definition: Protocol.h:184
clang::clangd::URI::resolvePath
static llvm::Expected< std::string > resolvePath(llvm::StringRef AbsPath, llvm::StringRef HintPath="")
Resolves AbsPath into a canonical path of its URI, by converting AbsPath to URI and resolving the URI...
Definition: URI.cpp:253
clang::clangd::CompletionItemKind::Folder
@ Folder
clang::clangd::DidChangeTextDocumentParams::forceRebuild
bool forceRebuild
Force a complete rebuild of the file, ignoring all cached state.
Definition: Protocol.h:732
clang::clangd::SymbolInformation::name
std::string name
The name of this symbol.
Definition: Protocol.h:1059
clang::clangd::ClientCapabilities::CompletionDocumentationFormat
MarkupKind CompletionDocumentationFormat
The documentation format that should be used for textDocument/completion.
Definition: Protocol.h:452
clang::clangd::FileChangeType::Created
@ Created
The file got created.
clang::clangd::CallHierarchyItem::tags
std::vector< SymbolTag > tags
Tags for this item.
Definition: Protocol.h:1464
clang::clangd::ParameterInformation::documentation
std::string documentation
The documentation of this parameter. Optional.
Definition: Protocol.h:1290
clang::clangd::TypeHierarchyItem::kind
SymbolKind kind
The kind of the hierarchy item. For instance, class or interface.
Definition: Protocol.h:1397
clang::clangd::FoldingRangeParams
Definition: Protocol.h:1763
clang::clangd::ClientCapabilities::CompletionSnippets
bool CompletionSnippets
Client supports snippets as insert text.
Definition: Protocol.h:422
clang::clangd::Location::range
Range range
Definition: Protocol.h:211
clang::clangd::SemanticToken::deltaLine
unsigned deltaLine
token line number, relative to the previous token
Definition: Protocol.h:1637
clang::clangd::InitializeParams
Definition: Protocol.h:540
clang::clangd::DocumentHighlight::range
Range range
The range this highlight applies to.
Definition: Protocol.h:1351
clang::clangd::URIForFile::fromURI
static llvm::Expected< URIForFile > fromURI(const URI &U, llvm::StringRef HintPath)
Definition: Protocol.cpp:58
clang::clangd::CompletionItemKind::Text
@ Text
clang::clangd::CodeActionParams::textDocument
TextDocumentIdentifier textDocument
The document in which the command was invoked.
Definition: Protocol.h:936
clang::clangd::SymbolKind::Class
@ Class
clang::clangd::CodeActionParams::context
CodeActionContext context
Context carrying additional information.
Definition: Protocol.h:942
clang::clangd::TextDocumentItem
Definition: Protocol.h:244
clang::clangd::ApplyWorkspaceEditResponse::failureReason
llvm::Optional< std::string > failureReason
Definition: Protocol.h:1121
clang::clangd::ASTNode::kind
std::string kind
The specific kind of node this is, such as "BinaryOperator".
Definition: Protocol.h:1822
clang::clangd::ASTParams::range
llvm::Optional< Range > range
The position of the node to be dumped.
Definition: Protocol.h:1809
clang::clangd::ParameterInformation::labelOffsets
llvm::Optional< std::pair< unsigned, unsigned > > labelOffsets
Inclusive start and exclusive end offsets withing the containing signature label.
Definition: Protocol.h:1287
clang::clangd::CallHierarchyIncomingCall
Represents an incoming call, e.g. a caller of a method or constructor.
Definition: Protocol.h:1496
clang::clangd::URI::parse
static llvm::Expected< URI > parse(llvm::StringRef Uri)
Parse a URI string "<scheme>:[//<authority>/]<path>".
Definition: URI.cpp:177
clang::clangd::InitializeParams::rawCapabilities
llvm::json::Object rawCapabilities
The same data as capabilities, but not parsed (to expose to modules).
Definition: Protocol.h:564
clang::clangd::WorkspaceSymbolParams::limit
llvm::Optional< int > limit
Max results to return, overriding global default.
Definition: Protocol.h:1109
clang::clangd::DocumentSymbol::children
std::vector< DocumentSymbol > children
Children of this symbol, e.g. properties of a class.
Definition: Protocol.h:1050
clang::clangd::SymbolKindBitset
std::bitset< SymbolKindMax+1 > SymbolKindBitset
Definition: Protocol.h:364
clang::clangd::CompletionItem
Definition: Protocol.h:1199
clang::clangd::SymbolDetails::containerName
std::string containerName
Definition: Protocol.h:1086
clang::clangd::DocumentFormattingParams
Definition: Protocol.h:800
clang::clangd::TypeHierarchyItem::range
Range range
The range enclosing this type hierarchy item not including leading/trailing whitespace but everything...
Definition: Protocol.h:1409
clang::clangd::TextDocumentItem::version
llvm::Optional< int64_t > version
The version number of this document (it will strictly increase after each change, including undo/redo...
Definition: Protocol.h:255
clang::clangd::SymbolKind
SymbolKind
A symbol kind.
Definition: Protocol.h:333
clang::clangd::WorkDoneProgressBegin::cancellable
bool cancellable
Controls if a cancel button should show to allow the user to cancel the long-running operation.
Definition: Protocol.h:602
clang::clangd::RenameParams::position
Position position
The position at which this request was sent.
Definition: Protocol.h:1336
clang::clangd::Diagnostic::range
Range range
The range at which the message applies.
Definition: Protocol.h:848
clang::clangd::MarkupContent::value
std::string value
Definition: Protocol.h:1167
clang::clangd::WorkDoneProgressReport::cancellable
llvm::Optional< bool > cancellable
Controls enablement state of a cancel button.
Definition: Protocol.h:630
clang::clangd::DocumentSymbolParams
Definition: Protocol.h:807
clang::clangd::ASTNode::range
llvm::Optional< Range > range
The range of the original source file covered by this node.
Definition: Protocol.h:1833
clang::clangd::OffsetEncoding::UTF8
@ UTF8
clang::clangd::CompletionItemKindBitset
std::bitset< CompletionItemKindMax+1 > CompletionItemKindBitset
Definition: Protocol.h:325
clang::clangd::Position::line
int line
Line position in a document (zero-based).
Definition: Protocol.h:155
clang::clangd::CodeAction::kind
llvm::Optional< std::string > kind
The kind of the code action.
Definition: Protocol.h:998
clang::clangd::SelectionRangeParams
Definition: Protocol.h:1704
clang::clangd::WorkDoneProgressBegin
To start progress reporting a $/progress notification with the following payload must be sent.
Definition: Protocol.h:592
clang::clangd::SymbolKind::TypeParameter
@ TypeParameter
clang::clangd::DiagnosticRelatedInformation::location
Location location
The location of this related diagnostic information.
Definition: Protocol.h:819
clang::clangd::CompletionItemKind::Enum
@ Enum
clang::clangd::CodeAction::title
std::string title
A short, human-readable, title for this code action.
Definition: Protocol.h:994
clang::clangd::DocumentHighlight::kind
DocumentHighlightKind kind
The highlight kind, default is DocumentHighlightKind.Text.
Definition: Protocol.h:1354
clang::clangd::SymbolDetails::name
std::string name
Definition: Protocol.h:1084
Protocol.h
clang::clangd::InlayHint
Inlay hint information.
Definition: Protocol.h:1570
clang::clangd::toTextKind
static llvm::StringRef toTextKind(MarkupKind Kind)
Definition: Protocol.cpp:885
clang::clangd::WorkspaceEdit::changes
std::map< std::string, std::vector< TextEdit > > changes
Holds changes to existing resources.
Definition: Protocol.h:948
clang::clangd::TypeHierarchyDirection::Both
@ Both
clang::clangd::SignatureInformation::parameters
std::vector< ParameterInformation > parameters
The parameters of this signature.
Definition: Protocol.h:1304
clang::clangd::URI::resolve
static llvm::Expected< std::string > resolve(const URI &U, llvm::StringRef HintPath="")
Resolves the absolute path of U.
Definition: URI.cpp:245
clang::clangd::Diagnostic
Definition: Protocol.h:846
clang::clangd::TextDocumentItem::uri
URIForFile uri
The text document's URI.
Definition: Protocol.h:246
clang::clangd::WorkDoneProgressEnd
Signals the end of progress reporting.
Definition: Protocol.h:650
clang::clangd::ClientCapabilities::offsetEncoding
llvm::Optional< std::vector< OffsetEncoding > > offsetEncoding
Supported encodings for LSP character offsets. (clangd extension).
Definition: Protocol.h:469
clang::clangd::ClientCapabilities::OffsetsInSignatureHelp
bool OffsetsInSignatureHelp
Client supports processing label offsets instead of a simple label string.
Definition: Protocol.h:439
ns1::ns2::A
@ A
Definition: CategoricalFeature.h:3
clang::clangd::CompletionContext::triggerCharacter
std::string triggerCharacter
The trigger character (a single character) that has trigger code complete.
Definition: Protocol.h:1152
clang::clangd::Position
Definition: Protocol.h:153
clang::clangd::CodeAction::edit
llvm::Optional< WorkspaceEdit > edit
The workspace edit this code action performs.
Definition: Protocol.h:1014
clang::clangd::InitializeParams::capabilities
ClientCapabilities capabilities
The capabilities provided by the client (editor or tool)
Definition: Protocol.h:562
clang::clangd::SymbolDetails::ID
SymbolID ID
Definition: Protocol.h:1095
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
clang::clangd::SymbolKind::Method
@ Method
clang::clangd::SymbolKind::Function
@ Function
clang::clangd::ExecuteCommandParams::argument
llvm::json::Value argument
Definition: Protocol.h:977
clang::clangd::FileStatus::state
std::string state
The human-readable string presents the current state of the file, can be shown in the UI (e....
Definition: Protocol.h:1627
clang::clangd::ClientCapabilities::RenamePrepareSupport
bool RenamePrepareSupport
The client supports testing for validity of rename operations before execution.
Definition: Protocol.h:477
clang::clangd::Unknown
@ Unknown
Definition: FuzzyMatch.h:56
clang::clangd::ClientCapabilities::HoverContentFormat
MarkupKind HoverContentFormat
The content format that should be used for Hover requests.
Definition: Protocol.h:473
clang::clangd::TweakArgs
Arguments for the 'applyTweak' command.
Definition: Protocol.h:960
clang::clangd::TypeHierarchyDirection::Children
@ Children
clang::clangd::ClientCapabilities::SignatureHelpDocumentationFormat
MarkupKind SignatureHelpDocumentationFormat
The documentation format that should be used for textDocument/signatureHelp.
Definition: Protocol.h:444
clang::clangd::SemanticToken
Specifies a single semantic token in the document.
Definition: Protocol.h:1635
clang::clangd::MemoryTree
A tree that can be used to represent memory usage of nested components while preserving the hierarchy...
Definition: MemoryTree.h:30
clang::clangd::SignatureInformation::label
std::string label
The label of this signature. Mandatory.
Definition: Protocol.h:1298
clang::clangd::SemanticTokensOrDelta::edits
llvm::Optional< std::vector< SemanticTokensEdit > > edits
Set if we computed edits relative to a previous set of tokens.
Definition: Protocol.h:1698
clang::clangd::SignatureHelp::signatures
std::vector< SignatureInformation > signatures
The resulting signatures.
Definition: Protocol.h:1314
clang::clangd::DocumentSymbolParams::textDocument
TextDocumentIdentifier textDocument
Definition: Protocol.h:809
clang::clangd::DidChangeWatchedFilesParams
Definition: Protocol.h:756
clang::clangd::ASTNode::role
std::string role
The general kind of node, such as "expression" Corresponds to the base AST node type such as Expr.
Definition: Protocol.h:1818
clang::clangd::PublishDiagnosticsParams::uri
URIForFile uri
The URI for which diagnostic information is reported.
Definition: Protocol.h:909
clang::clangd::Diag
A top-level diagnostic that may have Notes and Fixes.
Definition: Diagnostics.h:94
clang::clangd::toJSON
llvm::json::Value toJSON(const FuzzyFindRequest &Request)
Definition: Index.cpp:45
Logger.h
clang::clangd::WorkDoneProgressReport::message
llvm::Optional< std::string > message
Optional, more detailed associated progress message.
Definition: Protocol.h:637
clang::clangd::SemanticToken::deltaStart
unsigned deltaStart
token start character, relative to the previous token (relative to 0 or the previous token's start if...
Definition: Protocol.h:1640
Args
llvm::json::Object Args
Definition: Trace.cpp:138
clang::clangd::SymbolKind::Interface
@ Interface
clang::clangd::OffsetEncoding::UTF16
@ UTF16
clang::clangd::TypeHierarchyItem::name
std::string name
The human readable name of the hierarchy item.
Definition: Protocol.h:1390
clang::clangd::Symbol
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
clang::clangd::SemanticToken::tokenType
unsigned tokenType
will be looked up in SemanticTokensLegend.tokenTypes
Definition: Protocol.h:1644
clang::clangd::FileChangeType::Deleted
@ Deleted
The file got deleted.
clang::clangd::CallHierarchyOutgoingCall
Represents an outgoing call, e.g.
Definition: Protocol.h:1515
clang::clangd::fromJSON
bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request, llvm::json::Path P)
Definition: Index.cpp:30
clang::clangd::TextDocumentIdentifier
Definition: Protocol.h:128
clang::clangd::DocumentSymbol::detail
std::string detail
More detail for this symbol, e.g the signature of a function.
Definition: Protocol.h:1031
clang::clangd::DocumentRangeFormattingParams
Definition: Protocol.h:777
clang::clangd::WorkDoneProgressCreateParams::token
llvm::json::Value token
The token to be used to report progress.
Definition: Protocol.h:576
clang::clangd::FileStatus::uri
URIForFile uri
The text document's URI.
Definition: Protocol.h:1624
clang::clangd::CallHierarchyItem::data
std::string data
An optional 'data' field, which can be used to identify a call hierarchy item in an incomingCalls or ...
Definition: Protocol.h:1483
clang::clangd::ExecuteCommandParams::command
std::string command
The identifier of the actual command handler.
Definition: Protocol.h:973
clang::clangd::FoldingRangeParams::textDocument
TextDocumentIdentifier textDocument
Definition: Protocol.h:1764
clang::clangd::indexSymbolKindToSymbolKind
SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind)
Definition: Protocol.cpp:250
clang::clangd::Diagnostic::data
llvm::json::Object data
A data entry field that is preserved between a textDocument/publishDiagnostics notification and textD...
Definition: Protocol.h:890
clang::clangd::DocumentSymbol::selectionRange
Range selectionRange
The range that should be selected and revealed when this symbol is being picked, e....
Definition: Protocol.h:1047
clang::clangd::CodeDescription
Structure to capture a description for an error code.
Definition: Protocol.h:839
clang::clangd::TextDocumentItem::languageId
std::string languageId
The text document's language identifier.
Definition: Protocol.h:249
clang::clangd::CompletionItem::sortText
std::string sortText
A string that should be used when comparing this item with other items.
Definition: Protocol.h:1217
clang::clangd::InsertTextFormat::Missing
@ Missing
clang::clangd::toString
static const char * toString(OffsetEncoding OE)
Definition: Protocol.cpp:1374
clang::clangd::Position::character
int character
Character offset on a line in a document (zero-based).
Definition: Protocol.h:160
clang::clangd::ReferenceParams::context
ReferenceContext context
Definition: Protocol.h:1616
clang::clangd::CompletionContext::triggerKind
CompletionTriggerKind triggerKind
How the completion was triggered.
Definition: Protocol.h:1149
clang::clangd::CompletionItemKind::Struct
@ Struct
clang::clangd::TextDocumentPositionParams::position
Position position
The position inside the text document.
Definition: Protocol.h:1131
clang::clangd::Range::end
Position end
The range's end position.
Definition: Protocol.h:187
clang::clangd::SymbolID::str
std::string str() const
Definition: SymbolID.cpp:34
clang::clangd::DocumentSymbol
Represents programming constructs like variables, classes, interfaces etc.
Definition: Protocol.h:1026
clang::clangd::SemanticTokensOrDelta::tokens
llvm::Optional< std::vector< SemanticToken > > tokens
Set if we computed a fresh set of tokens.
Definition: Protocol.h:1700
clang::clangd::URIForFile
Definition: Protocol.h:81
clang::clangd::SemanticToken::length
unsigned length
the length of the token. A token cannot be multiline
Definition: Protocol.h:1642
clang::clangd::URIForFile::uri
std::string uri() const
Definition: Protocol.h:104
clang::clangd::DidChangeConfigurationParams
Definition: Protocol.h:763
clang::clangd::SymbolKind::Enum
@ Enum
clang::clangd::DidChangeWatchedFilesParams::changes
std::vector< FileEvent > changes
The actual file events.
Definition: Protocol.h:758
clang::clangd::TypeHierarchyItem::children
llvm::Optional< std::vector< TypeHierarchyItem > > children
If this type hierarchy item is resolved, it contains the direct children of the current item.
Definition: Protocol.h:1424
clang::clangd::SelectionRange
Definition: Protocol.h:1714
clang::clangd::MemoryTree::children
const llvm::DenseMap< llvm::StringRef, MemoryTree > & children() const
Returns edges to direct children of this node.
Definition: MemoryTree.cpp:42
clang::clangd::operator<<
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
Definition: CodeComplete.cpp:2172
clang::clangd::CodeAction::command
llvm::Optional< Command > command
A command this code action executes.
Definition: Protocol.h:1018
clang::clangd::DocumentFormattingParams::textDocument
TextDocumentIdentifier textDocument
The document to format.
Definition: Protocol.h:802
clang::clangd::CompletionItemKind
CompletionItemKind
The kind of a completion entry.
Definition: Protocol.h:291
clang::clangd::TypeHierarchyItem::uri
URIForFile uri
The URI of the text document where this type hierarchy item belongs to.
Definition: Protocol.h:1403
clang::clangd::DocumentHighlightKind::Write
@ Write
clang::clangd::SymbolDetails
Represents information about identifier.
Definition: Protocol.h:1083
clang::clangd::ConfigurationSettings
Clangd extension: parameters configurable at any time, via the workspace/didChangeConfiguration notif...
Definition: Protocol.h:513
clang::clangd::DocumentLinkParams
Parameters for the document link request.
Definition: Protocol.h:1728
clang::clangd::ClientCapabilities::DiagnosticRelatedInformation
bool DiagnosticRelatedInformation
Whether the client accepts diagnostics with related locations.
Definition: Protocol.h:413
clang::clangd::SymbolDetails::USR
std::string USR
Unified Symbol Resolution identifier This is an opaque string uniquely identifying a symbol.
Definition: Protocol.h:1093
clang::clangd::ExecuteCommandParams
Definition: Protocol.h:971
clang::clangd::SymbolKind::Module
@ Module
SymbolKind
clang::find_all_symbols::SymbolInfo::SymbolKind SymbolKind
Definition: SymbolInfo.cpp:19
clang::clangd::SignatureHelp::activeSignature
int activeSignature
The active signature.
Definition: Protocol.h:1317
clang::clangd::TextDocumentItem::text
std::string text
The content of the opened text document.
Definition: Protocol.h:258
clang::clangd::InitializeParams::initializationOptions
InitializationOptions initializationOptions
User-provided initialization options.
Definition: Protocol.h:570
clang::clangd::encodeTokens
static llvm::json::Value encodeTokens(llvm::ArrayRef< SemanticToken > Toks)
Definition: Protocol.cpp:1091
clang::clangd::SymbolInformation::score
llvm::Optional< float > score
The score that clangd calculates to rank the returned symbols.
Definition: Protocol.h:1076
clang::clangd::CallHierarchyIncomingCallsParams
The parameter of a callHierarchy/incomingCalls request.
Definition: Protocol.h:1489
Entry
Definition: Modularize.cpp:428
clang::clangd::TypeHierarchyParams::resolve
int resolve
The hierarchy levels to resolve. 0 indicates no level.
Definition: Protocol.h:1380
clang::clangd::CompletionItemKind::File
@ File
clang::clangd::CodeActionContext::diagnostics
std::vector< Diagnostic > diagnostics
An array of diagnostics known on the client side overlapping the range provided to the textDocument/c...
Definition: Protocol.h:924
clang::clangd::SelectionRangeParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1706
clang::clangd::WorkDoneProgressReport
Reporting progress is done using the following payload.
Definition: Protocol.h:618
clang::clangd::PublishDiagnosticsParams
Definition: Protocol.h:907
clang::clangd::MemoryTree::self
size_t self() const
Returns total number of bytes used by this node only.
Definition: MemoryTree.h:65
clang::clangd::ClientCapabilities::WorkDoneProgress
bool WorkDoneProgress
The client supports progress notifications.
Definition: Protocol.h:481
clang::clangd::MarkupKind
MarkupKind
Definition: Protocol.h:392
clang::clangd::CodeAction::diagnostics
llvm::Optional< std::vector< Diagnostic > > diagnostics
The diagnostics that this code action resolves.
Definition: Protocol.h:1004
clang::clangd::MessageType
MessageType
Definition: Protocol.h:657
clang::clangd::TypeHierarchyDirection
TypeHierarchyDirection
Definition: Protocol.h:1371
clang::clangd::TypeHierarchyParams
The type hierarchy params is an extension of the TextDocumentPositionsParams with optional properties...
Definition: Protocol.h:1378
clang::clangd::SymbolKind::Variable
@ Variable
clang::clangd::TypeHierarchyItem
Definition: Protocol.h:1388
clang::clangd::DidChangeTextDocumentParams
Definition: Protocol.h:713
clang::clangd::CompletionTriggerKind
CompletionTriggerKind
Definition: Protocol.h:1136
clang::clangd::InlayHintKind::Type
@ Type
An inlay hint that for a type annotation.
clang::clangd::ConfigurationSettings::compilationDatabaseChanges
std::map< std::string, ClangdCompileCommand > compilationDatabaseChanges
Definition: Protocol.h:516
clang::clangd::TypeHierarchyItem::detail
llvm::Optional< std::string > detail
Optional detail for the hierarchy item.
Definition: Protocol.h:1394
clang::clangd::TypeHierarchyItem::deprecated
bool deprecated
true if the hierarchy item is deprecated. Otherwise, false.
Definition: Protocol.h:1400
clang::clangd::SignatureInformation
Represents the signature of something callable.
Definition: Protocol.h:1295
clang::clangd::ClientCapabilities::SemanticTokenRefreshSupport
bool SemanticTokenRefreshSupport
Whether the client implementation supports a refresh request sent from the server to the client.
Definition: Protocol.h:495
clang::clangd::ClientCapabilities::CodeActionStructure
bool CodeActionStructure
Client supports CodeAction return value for textDocument/codeAction.
Definition: Protocol.h:456
clang::clangd::ASTParams
Payload for textDocument/ast request.
Definition: Protocol.h:1802
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:121
clang::clangd::DocumentSymbol::kind
SymbolKind kind
The kind of this symbol.
Definition: Protocol.h:1034
clang::clangd::CompletionItemKind::EnumMember
@ EnumMember
clang::clangd::WorkDoneProgressBegin::percentage
bool percentage
Optional progress percentage to display (value 100 is considered 100%).
Definition: Protocol.h:613
clang::clangd::InlayHintsParams::range
llvm::Optional< Range > range
The visible document range for which inlay hints should be computed.
Definition: Protocol.h:1534
clang::clangd::DidChangeTextDocumentParams::contentChanges
std::vector< TextDocumentContentChangeEvent > contentChanges
The actual content changes.
Definition: Protocol.h:720
clang::clangd::DidChangeTextDocumentParams::textDocument
VersionedTextDocumentIdentifier textDocument
The document that did change.
Definition: Protocol.h:717
clang::clangd::TypeHierarchyParams::direction
TypeHierarchyDirection direction
The direction of the hierarchy levels to resolve.
Definition: Protocol.h:1383
clang::clangd::TextDocumentPositionParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1128
clang::clangd::DidSaveTextDocumentParams::textDocument
TextDocumentIdentifier textDocument
The document that was saved.
Definition: Protocol.h:695
clang::clangd::WorkspaceSymbolParams
The parameters of a Workspace Symbol Request.
Definition: Protocol.h:1102
clang::clangd::CompletionParams
Definition: Protocol.h:1156
clang::clangd::ClangdCompileCommand::compilationCommand
std::vector< std::string > compilationCommand
Definition: Protocol.h:505
clang::clangd::Range
Definition: Protocol.h:182
clang::clangd::FileEvent::type
FileChangeType type
The change type.
Definition: Protocol.h:752
clang::clangd::SignatureHelp
Represents the signature of a callable.
Definition: Protocol.h:1311
clang::clangd::FileChangeType
FileChangeType
Definition: Protocol.h:737
clang::clangd::SemanticTokens
A versioned set of tokens.
Definition: Protocol.h:1651
clang::clangd::VersionedTextDocumentIdentifier::version
llvm::Optional< std::int64_t > version
The version number of this document.
Definition: Protocol.h:147
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
clang::clangd::ShowMessageParams::message
std::string message
The actual message.
Definition: Protocol.h:675
clang::clangd::Diagnostic::message
std::string message
The diagnostic's message.
Definition: Protocol.h:865
clang::clangd::URIForFile::URIForFile
URIForFile()=default
clang::clangd::URIForFile::canonicalize
static URIForFile canonicalize(llvm::StringRef AbsPath, llvm::StringRef TUPath)
Canonicalizes AbsPath via URI.
Definition: Protocol.cpp:45
clang::clangd::ApplyWorkspaceEditResponse
Definition: Protocol.h:1119
if
if(CLANG_PLUGIN_SUPPORT) export_executable_symbols_for_plugins(clang-tidy) endif() install(PROGRAMS clang-tidy-diff.py DESTINATION "$
Definition: clang-tidy/tool/CMakeLists.txt:59
clang::clangd::Diagnostic::severity
int severity
The diagnostic's severity.
Definition: Protocol.h:852
clang::clangd::ParameterInformation::labelString
std::string labelString
The label of this parameter. Ignored when labelOffsets is set.
Definition: Protocol.h:1281
clang::clangd::InitializeParams::trace
llvm::Optional< TraceLevel > trace
The initial trace setting. If omitted trace is disabled ('off').
Definition: Protocol.h:567
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::PublishDiagnosticsParams::version
llvm::Optional< int64_t > version
The version number of the document the diagnostics are published for.
Definition: Protocol.h:913
clang::clangd::WorkDoneProgressReport::percentage
llvm::Optional< unsigned > percentage
Optional progress percentage to display (value 100 is considered 100%).
Definition: Protocol.h:645
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:160
clang::clangd::FoldingRange
Stores information about a region of code that can be folded.
Definition: Protocol.h:1770
clang::clangd::CodeAction::REFACTOR_KIND
const static llvm::StringLiteral REFACTOR_KIND
Definition: Protocol.h:1000
clang::clangd::DidSaveTextDocumentParams
Definition: Protocol.h:693
clang::clangd::TypeHierarchyItem::parents
llvm::Optional< std::vector< TypeHierarchyItem > > parents
If this type hierarchy item is resolved, it contains the direct parents.
Definition: Protocol.h:1419
clang::clangd::CallHierarchyItem::range
Range range
The range enclosing this symbol not including leading / trailing whitespace but everything else,...
Definition: Protocol.h:1474
clang::clangd::OffsetEncoding
OffsetEncoding
Definition: Protocol.h:376
clang::clangd::TextDocumentContentChangeEvent::range
llvm::Optional< Range > range
The range of the document that changed.
Definition: Protocol.h:702
clang::clangd::FileStatus
Clangd extension: indicates the current state of the file in clangd, sent from server via the textDoc...
Definition: Protocol.h:1622
clang::clangd::TextDocumentContentChangeEvent
Definition: Protocol.h:700
clang::clangd::WorkspaceSymbolParams::query
std::string query
A query string to filter symbols by.
Definition: Protocol.h:1105
clang::clangd::DocumentSymbol::deprecated
bool deprecated
Indicates if this symbol is deprecated.
Definition: Protocol.h:1037
clang::clangd::ClientCapabilities::TheiaSemanticHighlighting
bool TheiaSemanticHighlighting
Client supports Theia semantic highlighting extension.
Definition: Protocol.h:466
clang::clangd::CodeActionParams
Definition: Protocol.h:934
clang::clangd::operator<
bool operator<(const Ref &L, const Ref &R)
Definition: Ref.h:95
clang::clangd::TextDocumentPositionParams
Definition: Protocol.h:1126
clang::clangd::InitializeParams::rootPath
llvm::Optional< std::string > rootPath
The rootPath of the workspace.
Definition: Protocol.h:551
clang::clangd::InitializationOptions
Clangd extension: parameters configurable at initialize time.
Definition: Protocol.h:523
clang::clangd::DidCloseTextDocumentParams::textDocument
TextDocumentIdentifier textDocument
The document that was closed.
Definition: Protocol.h:688
clang::clangd::CallHierarchyItem
Represents programming constructs like functions or constructors in the context of call hierarchy.
Definition: Protocol.h:1456
clang::clangd::Diagnostic::code
std::string code
The diagnostic's code. Can be omitted.
Definition: Protocol.h:855
clang::clangd::SymbolKind::EnumMember
@ EnumMember
clang::clangd::RenameParams::textDocument
TextDocumentIdentifier textDocument
The document that was opened.
Definition: Protocol.h:1333
clang::clangd::DocumentOnTypeFormattingParams
Definition: Protocol.h:787
clang::clangd::TextEdit
Definition: Protocol.h:228
clang::clangd::SignatureHelp::activeParameter
int activeParameter
The active parameter of the active signature.
Definition: Protocol.h:1320
clang::clangd::OffsetEncoding::UnsupportedEncoding
@ UnsupportedEncoding
clang::clangd::SymbolInformation::containerName
std::string containerName
The name of the symbol containing this symbol.
Definition: Protocol.h:1068
clang::clangd::RenameParams
Definition: Protocol.h:1331
clang::clangd::ApplyWorkspaceEditParams
Definition: Protocol.h:1114
clang::clangd::CompletionParams::limit
llvm::Optional< int > limit
Max results to return, overriding global default.
Definition: Protocol.h:1161
clang::clangd::TraceLevel::Off
@ Off
clang::clangd::SymbolKind::Namespace
@ Namespace
clang::clangd::operator==
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition: Headers.cpp:368
clang::clangd::ClientCapabilities::ImplicitProgressCreation
bool ImplicitProgressCreation
The client supports implicit $/progress work-done progress streams, without a preceding window/workDo...
Definition: Protocol.h:487
clang::clangd::DidOpenTextDocumentParams
Definition: Protocol.h:679
clang::clangd::TraceLevel::Verbose
@ Verbose
clang::clangd::DocumentSymbol::name
std::string name
The name of this symbol.
Definition: Protocol.h:1028
clang::clangd::CompletionItemKind::Missing
@ Missing
clang::clangd::DocumentHighlightKind::Read
@ Read
clang::clangd::CompletionParams::context
CompletionContext context
Definition: Protocol.h:1157
clang::clangd::ClientCapabilities::SemanticTokens
bool SemanticTokens
Client advertises support for the semanticTokens feature.
Definition: Protocol.h:461
clang::clangd::ReferenceParams
Definition: Protocol.h:1615
clang::clangd::InlayHintKind
InlayHintKind
Inlay hint kinds.
Definition: Protocol.h:1539
URI.h
clang::clangd::SymbolKind::File
@ File
clang::clangd::ASTNode::arcana
std::string arcana
A one-line dump of detailed information about the node.
Definition: Protocol.h:1830
clang::clangd::ParameterInformation
A single parameter of a particular signature.
Definition: Protocol.h:1278
clang::clangd::DocumentLinkParams::textDocument
TextDocumentIdentifier textDocument
The document to provide document links for.
Definition: Protocol.h:1730
clang::clangd::LSPError::ID
static char ID
Definition: Protocol.h:67
clang::clangd::InlayHintsParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1528
clang::clangd::TextEdit::newText
std::string newText
The string to be inserted.
Definition: Protocol.h:235
Field
const FieldDecl * Field
Definition: MemberwiseConstructor.cpp:260
ns1::ns2::B
@ B
Definition: CategoricalFeature.h:3
clang::clangd::SymbolInformation::location
Location location
The location of this symbol.
Definition: Protocol.h:1065
Out
CompiledFragmentImpl & Out
Definition: ConfigCompile.cpp:99
clang::clangd::ClientCapabilities::CancelsStaleRequests
bool CancelsStaleRequests
Whether the client claims to cancel stale requests.
Definition: Protocol.h:491
clang::clangd::SemanticTokensDeltaParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1675
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:61
clang::clangd::MarkupContent
Definition: Protocol.h:1165
clang::clangd::ASTNode::children
std::vector< ASTNode > children
Nodes nested within this one, such as the operands of a BinaryOperator.
Definition: Protocol.h:1835
clang::clangd::InitializeParams::rootUri
llvm::Optional< URIForFile > rootUri
The rootUri of the workspace.
Definition: Protocol.h:556
clang::clangd::DiagnosticRelatedInformation
Represents a related message and source code location for a diagnostic.
Definition: Protocol.h:817
clang::clangd::ResolveTypeHierarchyItemParams::direction
TypeHierarchyDirection direction
The direction of the hierarchy levels to resolve.
Definition: Protocol.h:1443
clang::clangd::CompletionContext
Definition: Protocol.h:1147
clang::clangd::TextDocumentContentChangeEvent::text
std::string text
The new text of the range/document.
Definition: Protocol.h:708
clang::clangd::ASTParams::textDocument
TextDocumentIdentifier textDocument
The text document.
Definition: Protocol.h:1804
Tag
HTMLTag Tag
Definition: HTMLGenerator.cpp:90
clang::clangd::CallHierarchyOutgoingCallsParams
The parameter of a callHierarchy/outgoingCalls request.
Definition: Protocol.h:1507
clang::clangd::CompletionItemKind::TypeParameter
@ TypeParameter
clang::clangd::ASTNode
Simplified description of a clang AST node.
Definition: Protocol.h:1815
clang::clangd::CompletionItemKindMin
constexpr auto CompletionItemKindMin
Definition: Protocol.h:321
clang::clangd::ResolveTypeHierarchyItemParams::item
TypeHierarchyItem item
The item to resolve.
Definition: Protocol.h:1437
clang::clangd::ApplyWorkspaceEditParams::edit
WorkspaceEdit edit
Definition: Protocol.h:1115
clang::clangd::TextEdit::range
Range range
The range of the text document to be manipulated.
Definition: Protocol.h:231
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
clang::clangd::ShowMessageParams
The show message notification is sent from a server to a client to ask the client to display a partic...
Definition: Protocol.h:671
clang::clangd::CodeAction::INFO_KIND
const static llvm::StringLiteral INFO_KIND
Definition: Protocol.h:1001
clang::clangd::SymbolKind::Constructor
@ Constructor
clang::clangd::CodeActionContext
Definition: Protocol.h:917
clang::clangd::URI
A URI describes the location of a source file.
Definition: URI.h:28
K
Kind K
Definition: Rename.cpp:436
clang::clangd::SymbolInformation::kind
SymbolKind kind
The kind of this symbol.
Definition: Protocol.h:1062
clang::clangd::ClientCapabilities::HasSignatureHelp
bool HasSignatureHelp
Client supports signature help.
Definition: Protocol.h:435
clang::clangd::VersionedTextDocumentIdentifier
Definition: Protocol.h:136
clang::clangd::WorkDoneProgressBegin::title
std::string title
Mandatory title of the progress operation.
Definition: Protocol.h:597
clang::clangd::CodeActionParams::range
Range range
The range for which the command was invoked.
Definition: Protocol.h:939
clang::clangd::SymbolKind::String
@ String
clang::clangd::DiagnosticRelatedInformation::message
std::string message
The message of this related diagnostic information.
Definition: Protocol.h:821
Value
static constexpr bool Value
Definition: SuspiciousCallArgumentCheck.cpp:72
clang::clangd::CallHierarchyItem::name
std::string name
The name of this item.
Definition: Protocol.h:1458
clang::clangd::TypeHierarchyItem::data
llvm::Optional< std::string > data
An optional 'data' field, which can be used to identify a type hierarchy item in a resolve request.
Definition: Protocol.h:1428
clang::clangd::RenameParams::newName
std::string newName
The new name of the symbol.
Definition: Protocol.h:1339
clang::clangd::SymbolKind::Property
@ Property
clang::clangd::SymbolKind::Struct
@ Struct
Path
std::vector< HeaderHandle > Path
Definition: PreprocessorTracker.cpp:525
clang::clangd::InlayHintsParams
A parameter literal used in inlay hint requests.
Definition: Protocol.h:1526
clang::clangd::adjustKindToCapability
SymbolKind adjustKindToCapability(SymbolKind Kind, SymbolKindBitset &SupportedSymbolKinds)
Definition: Protocol.cpp:232
clang::clangd::TextDocumentContentChangeEvent::rangeLength
llvm::Optional< int > rangeLength
The length of the range that got replaced.
Definition: Protocol.h:705
clang::clangd::CallHierarchyItem::kind
SymbolKind kind
The kind of this item.
Definition: Protocol.h:1461
clang::clangd::CodeAction::QUICKFIX_KIND
const static llvm::StringLiteral QUICKFIX_KIND
Definition: Protocol.h:999
clang::clangd::ResolveTypeHierarchyItemParams
Parameters for the typeHierarchy/resolve request.
Definition: Protocol.h:1435
clang::clangd::InlayHintKind::Parameter
@ Parameter
An inlay hint that is for a parameter.
clang::clangd::WorkDoneProgressCreateParams
Definition: Protocol.h:574