18 #include "llvm/Support/JSON.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/VersionTuple.h"
21 #include <type_traits>
23 using namespace clang;
34 Paren[Key] = std::move(Obj.value());
41 Paren[Key] = std::move(Array.value());
65 Version[
"major"] =
V.getMajor();
66 Version[
"minor"] =
V.getMinor().value_or(0);
67 Version[
"patch"] =
V.getSubminor().value_or(0);
75 Object serializeOperatingSystem(
const Triple &T) {
77 OS[
"name"] = T.getOSTypeName(T.getOS());
78 serializeObject(OS,
"minimumVersion",
79 serializeSemanticVersion(T.getMinimumSupportedOSVersion()));
87 Object serializePlatform(
const Triple &T) {
89 Platform[
"architecture"] = T.getArchName();
90 Platform[
"vendor"] = T.getVendorName();
91 Platform[
"operatingSystem"] = serializeOperatingSystem(T);
97 assert(Loc.
isValid() &&
"invalid source position");
100 SourcePosition[
"line"] = Loc.
getLine();
101 SourcePosition[
"character"] = Loc.
getColumn();
103 return SourcePosition;
112 bool IncludeFileURI =
false) {
114 serializeObject(
SourceLocation,
"position", serializeSourcePosition(Loc));
116 if (IncludeFileURI) {
119 FileURI += sys::path::convert_to_slash(Loc.
getFilename());
130 serializeObject(
SourceRange,
"start", serializeSourcePosition(BeginLoc));
131 serializeObject(
SourceRange,
"end", serializeSourcePosition(EndLoc));
150 serializeObject(Availbility,
"introducedVersion",
152 serializeObject(Availbility,
"deprecatedVersion",
154 serializeObject(Availbility,
"obsoletedVersion",
155 serializeSemanticVersion(Avail.
Obsoleted));
157 Availbility[
"isUnconditionallyUnavailable"] =
true;
159 Availbility[
"isUnconditionallyDeprecated"] =
true;
170 return "objective-c";
186 llvm_unreachable(
"Unsupported language kind");
189 llvm_unreachable(
"Unhandled language kind");
226 for (
const auto &CommentLine : Comment) {
228 Line[
"text"] = CommentLine.Text;
229 serializeObject(
Line,
"range",
230 serializeSourceRange(CommentLine.Begin, CommentLine.End));
231 LinesArray.emplace_back(std::move(
Line));
233 serializeArray(
DocComment,
"lines", LinesArray);
279 Fragment[
"spelling"] = F.Spelling;
281 if (!F.PreciseIdentifier.empty())
282 Fragment[
"preciseIdentifier"] = F.PreciseIdentifier;
283 Fragments.emplace_back(std::move(Fragment));
300 Names[
"title"] = Record.
Name;
301 serializeArray(Names,
"subHeading",
302 serializeDeclarationFragments(Record.
SubHeading));
307 serializeArray(Names,
"navigator",
308 serializeDeclarationFragments(NavigatorFragments));
319 auto AddLangPrefix = [&Lang](StringRef S) ->
std::string {
326 Kind[
"identifier"] = AddLangPrefix(
"func");
327 Kind[
"displayName"] =
"Function";
330 Kind[
"identifier"] = AddLangPrefix(
"var");
331 Kind[
"displayName"] =
"Global Variable";
334 Kind[
"identifier"] = AddLangPrefix(
"enum.case");
335 Kind[
"displayName"] =
"Enumeration Case";
338 Kind[
"identifier"] = AddLangPrefix(
"enum");
339 Kind[
"displayName"] =
"Enumeration";
342 Kind[
"identifier"] = AddLangPrefix(
"property");
343 Kind[
"displayName"] =
"Instance Property";
346 Kind[
"identifier"] = AddLangPrefix(
"struct");
347 Kind[
"displayName"] =
"Structure";
350 Kind[
"identifier"] = AddLangPrefix(
"ivar");
351 Kind[
"displayName"] =
"Instance Variable";
354 if (dyn_cast<ObjCMethodRecord>(&Record)->IsInstanceMethod) {
355 Kind[
"identifier"] = AddLangPrefix(
"method");
356 Kind[
"displayName"] =
"Instance Method";
358 Kind[
"identifier"] = AddLangPrefix(
"type.method");
359 Kind[
"displayName"] =
"Type Method";
363 Kind[
"identifier"] = AddLangPrefix(
"property");
364 Kind[
"displayName"] =
"Instance Property";
367 Kind[
"identifier"] = AddLangPrefix(
"class");
368 Kind[
"displayName"] =
"Class";
372 llvm_unreachable(
"Serializing standalone Objective-C category symbols is "
376 Kind[
"identifier"] = AddLangPrefix(
"protocol");
377 Kind[
"displayName"] =
"Protocol";
380 Kind[
"identifier"] = AddLangPrefix(
"macro");
381 Kind[
"displayName"] =
"Macro";
384 Kind[
"identifier"] = AddLangPrefix(
"typealias");
385 Kind[
"displayName"] =
"Type Alias";
392 template <
typename RecordTy>
393 Optional<Object> serializeFunctionSignatureMixinImpl(
const RecordTy &Record,
395 const auto &FS = Record.Signature;
400 serializeArray(Signature,
"returns",
401 serializeDeclarationFragments(FS.getReturnType()));
404 for (
const auto &
P : FS.getParameters()) {
407 serializeArray(Parameter,
"declarationFragments",
408 serializeDeclarationFragments(
P.Fragments));
409 Parameters.emplace_back(std::move(Parameter));
413 Signature[
"parameters"] = std::move(Parameters);
418 template <
typename RecordTy>
419 Optional<Object> serializeFunctionSignatureMixinImpl(
const RecordTy &Record,
434 template <
typename RecordTy>
435 void serializeFunctionSignatureMixin(Object &
Paren,
const RecordTy &Record) {
436 serializeObject(
Paren,
"functionSignature",
437 serializeFunctionSignatureMixinImpl(
443 void SymbolGraphSerializer::anchor() {}
446 const VersionTuple SymbolGraphSerializer::FormatVersion{0, 5, 3};
448 Object SymbolGraphSerializer::serializeMetadata()
const {
450 serializeObject(Metadata,
"formatVersion",
451 serializeSemanticVersion(FormatVersion));
456 Object SymbolGraphSerializer::serializeModule()
const {
460 Module[
"name"] = ProductName;
461 serializeObject(
Module,
"platform", serializePlatform(API.getTarget()));
465 bool SymbolGraphSerializer::shouldSkip(
const APIRecord &Record)
const {
472 if (Record.
Name.startswith(
"_"))
478 template <
typename RecordTy>
480 SymbolGraphSerializer::serializeAPIRecord(
const RecordTy &Record)
const {
481 if (shouldSkip(Record))
485 serializeObject(Obj,
"identifier",
486 serializeIdentifier(Record, API.getLanguage()));
487 serializeObject(Obj,
"kind", serializeSymbolKind(Record, API.getLanguage()));
488 serializeObject(Obj,
"names", serializeNames(Record));
491 serializeSourceLocation(Record.Location,
true));
492 serializeObject(Obj,
"availbility",
493 serializeAvailability(Record.Availability));
494 serializeObject(Obj,
"docComment", serializeDocComment(Record.Comment));
495 serializeArray(Obj,
"declarationFragments",
496 serializeDeclarationFragments(Record.Declaration));
499 Obj[
"accessLevel"] =
"public";
500 serializeArray(Obj,
"pathComponents", Array(PathComponents));
502 serializeFunctionSignatureMixin(Obj, Record);
507 template <
typename MemberTy>
508 void SymbolGraphSerializer::serializeMembers(
510 const SmallVector<std::unique_ptr<MemberTy>> &Members) {
511 for (
const auto &Member : Members) {
512 auto MemberPathComponentGuard = makePathComponentGuard(
Member->Name);
513 auto MemberRecord = serializeAPIRecord(*Member);
517 Symbols.emplace_back(std::move(*MemberRecord));
518 serializeRelationship(RelationshipKind::MemberOf, *Member, Record);
524 case RelationshipKind::MemberOf:
526 case RelationshipKind::InheritsFrom:
527 return "inheritsFrom";
528 case RelationshipKind::ConformsTo:
531 llvm_unreachable(
"Unhandled relationship kind");
534 void SymbolGraphSerializer::serializeRelationship(RelationshipKind
Kind,
538 Relationship[
"source"] = Source.
USR;
539 Relationship[
"target"] =
Target.USR;
540 Relationship[
"kind"] = getRelationshipString(
Kind);
542 Relationships.emplace_back(std::move(Relationship));
545 void SymbolGraphSerializer::serializeGlobalFunctionRecord(
547 auto GlobalPathComponentGuard = makePathComponentGuard(Record.
Name);
549 auto Obj = serializeAPIRecord(Record);
553 Symbols.emplace_back(std::move(*Obj));
556 void SymbolGraphSerializer::serializeGlobalVariableRecord(
558 auto GlobalPathComponentGuard = makePathComponentGuard(Record.
Name);
560 auto Obj = serializeAPIRecord(Record);
564 Symbols.emplace_back(std::move(*Obj));
567 void SymbolGraphSerializer::serializeEnumRecord(
const EnumRecord &Record) {
568 auto EnumPathComponentGuard = makePathComponentGuard(Record.
Name);
569 auto Enum = serializeAPIRecord(Record);
573 Symbols.emplace_back(std::move(*Enum));
574 serializeMembers(Record, Record.
Constants);
577 void SymbolGraphSerializer::serializeStructRecord(
const StructRecord &Record) {
578 auto StructPathComponentGuard = makePathComponentGuard(Record.
Name);
579 auto Struct = serializeAPIRecord(Record);
583 Symbols.emplace_back(std::move(*Struct));
584 serializeMembers(Record, Record.
Fields);
587 void SymbolGraphSerializer::serializeObjCContainerRecord(
589 auto ObjCContainerPathComponentGuard = makePathComponentGuard(Record.
Name);
590 auto ObjCContainer = serializeAPIRecord(Record);
594 Symbols.emplace_back(std::move(*ObjCContainer));
596 serializeMembers(Record, Record.
Ivars);
597 serializeMembers(Record, Record.
Methods);
600 for (
const auto &Protocol : Record.
Protocols)
602 serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol);
604 if (
auto *ObjCInterface = dyn_cast<ObjCInterfaceRecord>(&Record)) {
605 if (!ObjCInterface->SuperClass.empty())
608 serializeRelationship(RelationshipKind::InheritsFrom, Record,
609 ObjCInterface->SuperClass);
613 for (
const auto *Category : ObjCInterface->Categories) {
614 serializeMembers(Record,
Category->Ivars);
615 serializeMembers(Record,
Category->Methods);
616 serializeMembers(Record,
Category->Properties);
619 for (
const auto &Protocol :
Category->Protocols)
620 serializeRelationship(RelationshipKind::ConformsTo, Record, Protocol);
625 void SymbolGraphSerializer::serializeMacroDefinitionRecord(
627 auto MacroPathComponentGuard = makePathComponentGuard(Record.
Name);
628 auto Macro = serializeAPIRecord(Record);
633 Symbols.emplace_back(std::move(*Macro));
636 void SymbolGraphSerializer::serializeTypedefRecord(
647 auto TypedefPathComponentGuard = makePathComponentGuard(Record.
Name);
648 auto Typedef = serializeAPIRecord(Record);
654 Symbols.emplace_back(std::move(*Typedef));
657 SymbolGraphSerializer::PathComponentGuard
658 SymbolGraphSerializer::makePathComponentGuard(StringRef Component) {
659 return PathComponentGuard(PathComponents, Component);
664 serializeObject(Root,
"metadata", serializeMetadata());
665 serializeObject(Root,
"module", serializeModule());
668 for (
const auto &GlobalVar : API.getGlobalVariables())
669 serializeGlobalVariableRecord(*GlobalVar.second);
671 for (
const auto &GlobalFunction : API.getGlobalFunctions())
672 serializeGlobalFunctionRecord(*GlobalFunction.second);
675 for (
const auto &Enum : API.getEnums())
676 serializeEnumRecord(*Enum.second);
679 for (
const auto &Struct : API.getStructs())
680 serializeStructRecord(*Struct.second);
683 for (
const auto &ObjCInterface : API.getObjCInterfaces())
684 serializeObjCContainerRecord(*ObjCInterface.second);
687 for (
const auto &ObjCProtocol : API.getObjCProtocols())
688 serializeObjCContainerRecord(*ObjCProtocol.second);
690 for (
const auto &Macro : API.getMacros())
691 serializeMacroDefinitionRecord(*Macro.second);
693 for (
const auto &Typedef : API.getTypedefs())
694 serializeTypedefRecord(*Typedef.second);
696 Root[
"symbols"] = std::move(Symbols);
697 Root[
"relationships"] = std::move(Relationships);
703 Object root = serialize();
705 os << formatv(
"{0}",
Value(std::move(root))) <<
"\n";
707 os << formatv(
"{0:2}",
Value(std::move(root))) <<
"\n";