diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -487,6 +487,7 @@ SmallVector ReverseComponenents; ReverseComponenents.emplace_back(Record.USR, Record.Name, Record.getKind()); const auto *CurrentParent = &Record.ParentInformation; + bool FailedToFindParent = false; while (CurrentParent && !CurrentParent->empty()) { PathComponent CurrentParentComponent(CurrentParent->ParentUSR, CurrentParent->ParentName, @@ -509,8 +510,10 @@ // The parent record doesn't exist which means the symbol shouldn't be // treated as part of the current product. - if (!ParentRecord) - return true; + if (!ParentRecord) { + FailedToFindParent = true; + break; + } ReverseComponenents.push_back(std::move(CurrentParentComponent)); CurrentParent = &ParentRecord->ParentInformation; @@ -519,8 +522,9 @@ for (const auto &PC : reverse(ReverseComponenents)) ComponentTransformer(PC); - return false; + return FailedToFindParent; } + Object serializeParentContext(const PathComponent &PC, Language Lang) { Object ParentContextElem; ParentContextElem["usr"] = PC.USR; @@ -533,12 +537,15 @@ Array generateParentContexts(const RecordTy &Record, const APISet &API, Language Lang) { Array ParentContexts; - if (generatePathComponents( - Record, API, [Lang, &ParentContexts](const PathComponent &PC) { - ParentContexts.push_back(serializeParentContext(PC, Lang)); - })) - ParentContexts.clear(); - ParentContexts.pop_back(); + generatePathComponents(Record, API, + [Lang, &ParentContexts](const PathComponent &PC) { + ParentContexts.push_back( + serializeParentContext(PC, Lang)); + }); + + // The last component would be the record itself so let's remove it. + if (!ParentContexts.empty()) + ParentContexts.pop_back(); return ParentContexts; } @@ -865,6 +872,9 @@ if (!Record) return {}; + if (isa(Record)) + return {}; + Object Root; APIIgnoresList EmptyIgnores; SymbolGraphSerializer Serializer(API, EmptyIgnores, diff --git a/clang/test/Index/extract-api-cursor.m b/clang/test/Index/extract-api-cursor.m --- a/clang/test/Index/extract-api-cursor.m +++ b/clang/test/Index/extract-api-cursor.m @@ -25,6 +25,12 @@ - (void)derivedMethodWithValue:(id)value; @end +/// This won't show up in docs because we can't serialize it +@interface Derived () +/// Derived method in category docs, won't show up either. +- (void)derivedMethodInCategory; +@end + // RUN: c-index-test -single-symbol-sgfs local %s | FileCheck %s // Checking for Foo @@ -53,7 +59,7 @@ // Checking for baseProperty // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" +// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" // CHECK-SAME: "isSystem":false // CHECK-SAME: "usr":"c:@S@Foo"}] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(py)baseProperty","target":"c:objc(cs)Base" @@ -63,7 +69,7 @@ // Checking for baseMethodWithArg // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Base","usr":"c:objc(cs)Base"}] -// CHECK-SAME:"relatedSymbols":[] +// CHECK-SAME: "relatedSymbols":[] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Base(im)baseMethodWithArg:","target":"c:objc(cs)Base" // CHECK-SAME: "text":"Base method docs" // CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"} @@ -79,7 +85,7 @@ // Checking for protocolProperty // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.protocol","name":"Protocol","usr":"c:objc(pl)Protocol"}] -// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" +// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" // CHECK-SAME: "isSystem":false // CHECK-SAME: "usr":"c:@S@Foo"}] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(pl)Protocol(py)protocolProperty","target":"c:objc(pl)Protocol" @@ -89,7 +95,7 @@ // Checking for Derived // CHECK-NEXT: "parentContexts":[] -// CHECK-SAME:"relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" +// CHECK-SAME: "relatedSymbols":[{"accessLevel":"public","declarationLanguage":"objective-c" // CHECK-SAME: "isSystem":false // CHECK-SAME: "usr":"c:objc(cs)Base"}] // CHECK-SAME: "relationships":[{"kind":"inheritsFrom","source":"c:objc(cs)Derived","target":"c:objc(cs)Base" @@ -99,8 +105,11 @@ // Checking for derivedMethodWithValue // CHECK-NEXT: "parentContexts":[{"kind":"objective-c.class","name":"Derived","usr":"c:objc(cs)Derived"}] -// CHECK-SAME:"relatedSymbols":[] +// CHECK-SAME: "relatedSymbols":[] // CHECK-SAME: "relationships":[{"kind":"memberOf","source":"c:objc(cs)Derived(im)derivedMethodWithValue:","target":"c:objc(cs)Derived" // CHECK-SAME: "text":"Derived method docs" // CHECK-SAME: "kind":{"displayName":"Instance Method","identifier":"objective-c.method"} // CHECK-SAME: "title":"derivedMethodWithValue:" + +// CHECK-NOT: This won't show up in docs because we can't serialize it +// CHECK-NOT: Derived method in category docs, won't show up either.