diff --git a/lib/SymbolGraphGen/Edge.cpp b/lib/SymbolGraphGen/Edge.cpp index 296cc0960fee2..22f43eacc5402 100644 --- a/lib/SymbolGraphGen/Edge.cpp +++ b/lib/SymbolGraphGen/Edge.cpp @@ -25,12 +25,14 @@ void Edge::serialize(llvm::json::OStream &OS) const { // In case a dependent module isn't available, serialize a fallback name. auto TargetModuleName = Target->getModuleContext()->getName().str(); + if (TargetModuleName != Walker->M.getName().str()) { - auto TargetSymbolIdentifier = Walker->getSymbolIdentifier(Target); - auto TargetComponents = TargetSymbolIdentifier.SimpleComponents; + SmallVector, 8> TargetPathComponents; + Walker->getPathComponents(Target, TargetPathComponents); + SmallString<128> Scratch(TargetModuleName); - for (auto it = TargetComponents.begin(); - it != TargetComponents.end(); ++it) { + for (auto it = TargetPathComponents.begin(); + it != TargetPathComponents.end(); ++it) { Scratch.push_back('.'); Scratch.append(*it); } diff --git a/lib/SymbolGraphGen/Symbol.cpp b/lib/SymbolGraphGen/Symbol.cpp index c30210d75a1e1..425b98217b921 100644 --- a/lib/SymbolGraphGen/Symbol.cpp +++ b/lib/SymbolGraphGen/Symbol.cpp @@ -76,15 +76,30 @@ void Symbol::serializeKind(llvm::json::OStream &OS) const { void Symbol::serializeIdentifier(SymbolGraphASTWalker &Walker, llvm::json::OStream &OS) const { - AttributeRAII A("identifier", OS); - Walker.getSymbolIdentifier(VD).serialize(OS); + OS.attributeObject("identifier", [&](){ + OS.attribute("precise", Walker.getUSR(VD)); + OS.attribute("interfaceLanguage", "swift"); + }); +} + +void Symbol::serializePathComponents(SymbolGraphASTWalker &Walker, + llvm::json::OStream &OS) const { + OS.attributeArray("pathComponents", [&](){ + SmallVector, 8> PathComponents; + Walker.getPathComponents(VD, PathComponents); + for (auto Component : PathComponents) { + OS.value(Component); + } + }); } void Symbol::serializeNames(SymbolGraphASTWalker &Walker, llvm::json::OStream &OS) const { OS.attributeObject("names", [&](){ - auto Identifier = Walker.getSymbolIdentifier(VD); - OS.attribute("title", Identifier.SimpleComponents.back()); + SmallVector, 8> PathComponents; + Walker.getPathComponents(VD, PathComponents); + + OS.attribute("title", PathComponents.back()); // "navigator": null Walker.serializeSubheadingDeclarationFragments("subheading", VD, OS); // "prose": null @@ -370,6 +385,7 @@ void Symbol::serialize(SymbolGraphASTWalker &Walker, OS.object([&](){ serializeKind(OS); serializeIdentifier(Walker, OS); + serializePathComponents(Walker, OS); serializeNames(Walker, OS); serializeDocComment(Walker, OS); diff --git a/lib/SymbolGraphGen/Symbol.h b/lib/SymbolGraphGen/Symbol.h index 9cdbca5757164..6e22255596b50 100644 --- a/lib/SymbolGraphGen/Symbol.h +++ b/lib/SymbolGraphGen/Symbol.h @@ -24,46 +24,6 @@ namespace symbolgraphgen { struct AvailabilityDomain; struct SymbolGraphASTWalker; -/** - An identifier for a symbol that provides a globally unique identifier suitable for - internal lookups and a locally unique path for human use, such as a URL. - */ -struct SymbolIdentifier { - /** - A string that uniquely identifies a symbol within a module in the event of - ambiguities. A precise identifier need not be human readable. - */ - StringRef PreciseIdentifier; - - /** - The components for a "fully qualified" identifier. - */ - ArrayRef SimpleComponents; - - SymbolIdentifier(llvm::StringRef PreciseIdentifier, - ArrayRef SimpleComponents) - : PreciseIdentifier(PreciseIdentifier), - SimpleComponents(SimpleComponents) { - assert(!PreciseIdentifier.empty()); - } - - void serialize(llvm::json::OStream &OS) const { - OS.object([&](){ - OS.attribute("precise", PreciseIdentifier); - OS.attributeArray("simpleComponents", [&](){ - for (auto Component : SimpleComponents) { - OS.value(Component); - } - }); - }); - } - - bool operator==(const SymbolIdentifier &Other) const { - return PreciseIdentifier == Other.PreciseIdentifier && - SimpleComponents == Other.SimpleComponents; - } -}; - /// A symbol from a module: a node in a graph. struct Symbol { const ValueDecl *VD; @@ -76,6 +36,9 @@ struct Symbol { void serializeIdentifier(SymbolGraphASTWalker &Walker, llvm::json::OStream &OS) const; + void serializePathComponents(SymbolGraphASTWalker &Walker, + llvm::json::OStream &OS) const; + void serializeNames(SymbolGraphASTWalker &Walker, llvm::json::OStream &OS) const; diff --git a/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp b/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp index 2ce1337d65468..cc370438be29b 100644 --- a/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp +++ b/lib/SymbolGraphGen/SymbolGraphASTWalker.cpp @@ -149,24 +149,15 @@ StringRef SymbolGraphASTWalker::getUSR(const ValueDecl *VD) { return USR; } -SymbolIdentifier -SymbolGraphASTWalker::getSymbolIdentifier(const ValueDecl *VD) { - // Look in the symbol identifier cache for this declartion. - auto Found = SymbolIdentifierCache.find(VD); - if (Found != SymbolIdentifierCache.end()) { - return Found->getSecond(); - } - - // Not found; need to build a symbol identifier and add it to the cache. - auto PreciseIdentifier = getUSR(VD); - llvm::SmallVector SimpleIdentifierChain; - +void +SymbolGraphASTWalker::getPathComponents(const ValueDecl *VD, + SmallVectorImpl> &Components) { // Collect the spellings of the fully qualified identifier components. auto Decl = VD; while (Decl && !isa(Decl)) { SmallString<32> Scratch; Decl->getFullName().getString(Scratch); - SimpleIdentifierChain.push_back(Ctx.allocateCopy(Scratch.str())); + Components.push_back(Scratch); if (const auto *DC = Decl->getDeclContext()) { if (const auto *Proto = DC->getExtendedProtocolDecl()) { Decl = Proto; @@ -179,17 +170,9 @@ SymbolGraphASTWalker::getSymbolIdentifier(const ValueDecl *VD) { Decl = nullptr; } } - - // The list is leaf-to-root, but our list is root-to-leaf, so reverse it. - std::reverse(SimpleIdentifierChain.begin(), SimpleIdentifierChain.end()); - SymbolIdentifier Identifier { - PreciseIdentifier, - Ctx.allocateCopy(llvm::makeArrayRef(SimpleIdentifierChain)) - }; - - SymbolIdentifierCache.insert({VD, Identifier}); - return Identifier; + // The list is leaf-to-root, but our list is root-to-leaf, so reverse it. + std::reverse(Components.begin(), Components.end()); } PrintOptions SymbolGraphASTWalker::getDeclarationFragmentsPrintOptions() const { diff --git a/lib/SymbolGraphGen/SymbolGraphASTWalker.h b/lib/SymbolGraphGen/SymbolGraphASTWalker.h index fb3e3dc9b6d0d..adf15ec5d46ca 100644 --- a/lib/SymbolGraphGen/SymbolGraphASTWalker.h +++ b/lib/SymbolGraphGen/SymbolGraphASTWalker.h @@ -27,7 +27,6 @@ class ValueDecl; namespace symbolgraphgen { -struct SymbolIdentifier; struct SymbolGraph; struct SymbolGraphOptions; @@ -49,9 +48,6 @@ struct SymbolGraphASTWalker : public SourceEntityWalker { /// A context for allocations. markup::MarkupContext Ctx; - /// A cache of identifiers for declarations that may be seen more than once. - llvm::DenseMap SymbolIdentifierCache; - /// A cache of USRs for declarations. llvm::DenseMap USRCache; @@ -72,8 +68,8 @@ struct SymbolGraphASTWalker : public SourceEntityWalker { /// Get the USR of a declaration and add it to the local allocator. StringRef getUSR(const ValueDecl *VD); - /// Returns a `SymbolIdentifier` for a given declaration. - SymbolIdentifier getSymbolIdentifier(const ValueDecl *VD); + /// Returns an array of path components for a declaration. + void getPathComponents(const ValueDecl *VD, SmallVectorImpl> &Components); // MARK: - Declaration Fragments