diff --git a/include/mrdocs/Metadata/Info.hpp b/include/mrdocs/Metadata/Info.hpp index d105063cd..c0211421b 100644 --- a/include/mrdocs/Metadata/Info.hpp +++ b/include/mrdocs/Metadata/Info.hpp @@ -69,7 +69,7 @@ enum class InfoKind Guide, /// The symbol is a namespace alias Alias, - /// The symbol is a using declaration and using directive + /// The symbol is a using declaration Using, }; @@ -187,7 +187,7 @@ struct MRDOCS_VISIBLE /// Determine if this symbol is a namespace alias. constexpr bool isAlias() const noexcept { return Kind == InfoKind::Alias; } - /// Determine if this symbol is a using declaration or using directive. + /// Determine if this symbol is a using declaration. constexpr bool isUsing() const noexcept { return Kind == InfoKind::Using; } }; @@ -245,7 +245,7 @@ struct IsInfo : Info /// Determine if this symbol is a namespace alias. static constexpr bool isAlias() noexcept { return K == InfoKind::Alias; } - /// Determine if this symbol is a using declaration or using directive. + /// Determine if this symbol is a using declaration. static constexpr bool isUsing() noexcept { return K == InfoKind::Using; } protected: diff --git a/include/mrdocs/Metadata/Namespace.hpp b/include/mrdocs/Metadata/Namespace.hpp index ff5c7fec8..1dc94dfaf 100644 --- a/include/mrdocs/Metadata/Namespace.hpp +++ b/include/mrdocs/Metadata/Namespace.hpp @@ -37,6 +37,10 @@ struct NamespaceInfo { NamespaceFlags specs; + /** Namespaces nominated by using-directives. + */ + std::vector UsingDirectives; + //-------------------------------------------- explicit NamespaceInfo(SymbolID ID) noexcept diff --git a/include/mrdocs/Metadata/Using.hpp b/include/mrdocs/Metadata/Using.hpp index c17cae098..9198fe3d9 100644 --- a/include/mrdocs/Metadata/Using.hpp +++ b/include/mrdocs/Metadata/Using.hpp @@ -26,7 +26,6 @@ enum class UsingClass Normal = 0, // using Typename, // using typename Enum, // using enum - Namespace // using namespace (using directive) }; static constexpr @@ -38,24 +37,26 @@ toString(UsingClass const& value) case UsingClass::Normal: return "normal"; case UsingClass::Typename: return "typename"; case UsingClass::Enum: return "enum"; - case UsingClass::Namespace: return "namespace"; } return "unknown"; } -/** Info for using declarations and directives. +/** Info for using declarations. */ struct UsingInfo : IsInfo, SourceInfo { - /** The kind of using declaration/directive. */ + /** The kind of using declaration. + */ UsingClass Class = UsingClass::Normal; - /** The symbols being "used". */ + /** The symbols being "used". + */ std::vector UsingSymbols; - /** The qualifier for a using declaration/directive. */ + /** The qualifier for a using declaration. + */ std::unique_ptr Qualifier; //-------------------------------------------- diff --git a/share/mrdocs/addons/generator/asciidoc/partials/signature/using.adoc.hbs b/share/mrdocs/addons/generator/asciidoc/partials/signature/using.adoc.hbs index 183292175..a3d839112 100644 --- a/share/mrdocs/addons/generator/asciidoc/partials/signature/using.adoc.hbs +++ b/share/mrdocs/addons/generator/asciidoc/partials/signature/using.adoc.hbs @@ -1,5 +1 @@ -{{#if (eq symbol.class "namespace")~}} -using namespace {{>name-info symbol.nominatedSymbol~}} -{{else~}} -using {{#if (eq symbol.class "typename")}}typename {{/if}}{{#if (eq symbol.class "enum")}}enum {{/if}}{{#if symbol.qualifier}}{{>name-info symbol.qualifier}}::{{/if}}{{symbol.name~}} -{{/if}} +using {{#if (eq symbol.class "typename")}}typename {{/if}}{{#if (eq symbol.class "enum")}}enum {{/if}}{{#if symbol.qualifier}}{{>name-info symbol.qualifier}}::{{/if}}{{symbol.name~}} \ No newline at end of file diff --git a/share/mrdocs/addons/generator/asciidoc/partials/symbols/using.adoc.hbs b/share/mrdocs/addons/generator/asciidoc/partials/symbols/using.adoc.hbs index 7df469dc3..3ab2974f5 100644 --- a/share/mrdocs/addons/generator/asciidoc/partials/symbols/using.adoc.hbs +++ b/share/mrdocs/addons/generator/asciidoc/partials/symbols/using.adoc.hbs @@ -1,5 +1,5 @@ {{!-- symbols/using.adoc.hbs --}} -= Using {{#if (eq symbol.class "namespace")}}Directive{{else}}Declaration {{symbol.name}}{{/if}} += Using Declaration {{symbol.name}} {{symbol.doc.brief}} @@ -19,7 +19,6 @@ {{/if}} -{{#unless (eq symbol.class "namespace")}} == Introduced Symbols |=== @@ -28,4 +27,3 @@ | {{name}} {{/each}} |=== -{{/unless}} diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 3ff14dd1e..93aca8449 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -436,6 +436,8 @@ class ASTVisitor std::pair getOrCreateInfo(const SymbolID& id) { + assert(id != SymbolID::invalid && + "creating symbol with invalid SymbolID?"); Info* info = getInfo(id); bool created = ! info; if(! info) @@ -535,17 +537,6 @@ class ASTVisitor return false; } - // Handling UsingDirectiveDecl - if (const auto* UDD = dyn_cast(D)) - { - if (index::generateUSRForDecl(UDD->getNominatedNamespace(), usr_)) { - return true; - } - usr_.append("@UD"); - usr_.append(UDD->getQualifiedNameAsString()); - return false; - } - // Handling UsingDecl if (const auto* UD = dyn_cast(D)) { @@ -2194,31 +2185,6 @@ class ASTVisitor getParentNamespaces(I, D); } - - //------------------------------------------------ - - void - buildUsingDirective( - UsingInfo& I, - bool created, - UsingDirectiveDecl* D) - { - bool documented = parseRawComment(I.javadoc, D); - addSourceLocation(I, D->getBeginLoc(), true, documented); - - if(! created) - return; - - I.Class = UsingClass::Namespace; - // KRYSTIAN FIXME: we treat using-directives as having no name, - // and we store the full name of the nominated namespace in - // Qualifier. we should probably rename the member accordingly - I.Qualifier = buildNameInfo(D->getNominatedNamespaceAsWritten()); - - getParentNamespaces(I, D); - } - - //------------------------------------------------ void @@ -2593,12 +2559,23 @@ void ASTVisitor:: traverse(UsingDirectiveDecl* D) { - auto exp = getAsMrDocsInfo(D); - if(! exp) { return; } - auto [I, created] = *exp; - buildUsingDirective(I, created, D); -} + if(! shouldExtract(D, getAccess(D))) + return; + + Decl* PD = getParentDecl(D); + // only extract using-directives in namespace scope + if(! cast(PD)->isFileContext()) + return; + if(Info* PI = getInfo(extractSymbolID(PD))) + { + assert(PI->isNamespace()); + NamespaceInfo* NI = static_cast(PI); + getDependencyID( + D->getNominatedNamespaceAsWritten(), + NI->UsingDirectives.emplace_back()); + } +} //------------------------------------------------ // UsingDecl diff --git a/src/lib/AST/ASTVisitorHelpers.hpp b/src/lib/AST/ASTVisitorHelpers.hpp index ce22f4aad..84fb227b8 100644 --- a/src/lib/AST/ASTVisitorHelpers.hpp +++ b/src/lib/AST/ASTVisitorHelpers.hpp @@ -58,8 +58,10 @@ struct MrDocsType : std::type_identity {}; template <> struct MrDocsType : std::type_identity {}; +#if 0 template <> struct MrDocsType : std::type_identity {}; +#endif template <> struct MrDocsType : std::type_identity {}; diff --git a/src/lib/AST/AnyBlock.hpp b/src/lib/AST/AnyBlock.hpp index 718a71b5d..31ad7b3b2 100644 --- a/src/lib/AST/AnyBlock.hpp +++ b/src/lib/AST/AnyBlock.hpp @@ -1467,6 +1467,8 @@ class NamespaceBlock { case NAMESPACE_BITS: return decodeRecord(R, {&I->specs.raw}, Blob); + case NAMESPACE_USING_DIRECTIVES: + return decodeRecord(R, I->UsingDirectives, Blob); default: return TopLevelBlock::parseRecord(R, ID, Blob); } diff --git a/src/lib/AST/BitcodeIDs.hpp b/src/lib/AST/BitcodeIDs.hpp index d398eaaef..f652478e4 100644 --- a/src/lib/AST/BitcodeIDs.hpp +++ b/src/lib/AST/BitcodeIDs.hpp @@ -109,6 +109,7 @@ enum RecordID NAME_INFO_NAME, NAMESPACE_BITS, + NAMESPACE_USING_DIRECTIVES, TYPEINFO_KIND, TYPEINFO_IS_PACK, TYPEINFO_CVQUAL, diff --git a/src/lib/AST/BitcodeWriter.cpp b/src/lib/AST/BitcodeWriter.cpp index 3402dd2a9..4e92a7f9c 100644 --- a/src/lib/AST/BitcodeWriter.cpp +++ b/src/lib/AST/BitcodeWriter.cpp @@ -329,6 +329,7 @@ RecordIDNameMap = []() {JAVADOC_NODE_SYMBOLREF, {"JavadocNodeSymbol", &SymbolIDAbbrev}}, {JAVADOC_PARAM_DIRECTION, {"JavadocParamDirection", &Integer32Abbrev}}, {NAMESPACE_BITS, {"NamespaceBits", &Integer32ArrayAbbrev}}, + {NAMESPACE_USING_DIRECTIVES, {"NamespaceUsingDirectives", &SymbolIDsAbbrev}}, {NAME_INFO_KIND, {"NameKind", &Integer32Abbrev}}, {NAME_INFO_ID, {"NameID", &SymbolIDAbbrev}}, {NAME_INFO_NAME, {"NameName", &StringAbbrev}}, @@ -426,7 +427,7 @@ RecordsByBlock{ JAVADOC_NODE_PART, JAVADOC_NODE_SYMBOLREF}}, // NamespaceInfo {BI_NAMESPACE_BLOCK_ID, - {NAMESPACE_BITS}}, + {NAMESPACE_BITS, NAMESPACE_USING_DIRECTIVES}}, // RecordInfo {BI_RECORD_BLOCK_ID, {RECORD_KEY_KIND, RECORD_IS_TYPE_DEF, RECORD_BITS}}, @@ -1108,6 +1109,7 @@ emitBlock( emitInfoPart(I); emitScopeInfo(I); emitRecord({I.specs.raw}, NAMESPACE_BITS); + emitRecord(I.UsingDirectives, NAMESPACE_USING_DIRECTIVES); } void diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index c9e86df40..7ffa9a6aa 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -425,9 +425,6 @@ XMLWriter:: case UsingClass::Enum: classStr = "using enum"; break; - case UsingClass::Namespace: - classStr = "using namespace"; - break; default: MRDOCS_UNREACHABLE(); } diff --git a/src/lib/Metadata/DomMetadata.cpp b/src/lib/Metadata/DomMetadata.cpp index d772ceefa..53b3408ac 100644 --- a/src/lib/Metadata/DomMetadata.cpp +++ b/src/lib/Metadata/DomMetadata.cpp @@ -737,6 +737,8 @@ DomInfo::construct() const std::make_shared( makeTranche(I_, *domCorpus_)), domCorpus_)); + entries.emplace_back("usingDirectives", dom::newArray( + I_.UsingDirectives, domCorpus_)); } if constexpr(T::isRecord()) { @@ -875,15 +877,8 @@ DomInfo::construct() const if constexpr(T::isUsing()) { entries.emplace_back("class", toString(I_.Class)); - if (I_.Class == UsingClass::Namespace) - { - entries.emplace_back("nominatedSymbol", domCreate(I_.Qualifier, domCorpus_)); - } - else - { - entries.emplace_back("symbols", dom::newArray(I_.UsingSymbols, domCorpus_)); - entries.emplace_back("qualifier", domCreate(I_.Qualifier, domCorpus_)); - } + entries.emplace_back("symbols", dom::newArray(I_.UsingSymbols, domCorpus_)); + entries.emplace_back("qualifier", domCreate(I_.Qualifier, domCorpus_)); } if constexpr(T::isEnumerator()) { diff --git a/src/lib/Metadata/Finalize.cpp b/src/lib/Metadata/Finalize.cpp index 76ffb6a61..90b0af062 100644 --- a/src/lib/Metadata/Finalize.cpp +++ b/src/lib/Metadata/Finalize.cpp @@ -274,6 +274,7 @@ class Finalizer check(I.Namespace); check(I.Members); finalize(I.javadoc); + finalize(I.UsingDirectives); // finalize(I.Specializations); } diff --git a/src/lib/Metadata/Reduce.cpp b/src/lib/Metadata/Reduce.cpp index 3f51cbc12..36a8e26d3 100644 --- a/src/lib/Metadata/Reduce.cpp +++ b/src/lib/Metadata/Reduce.cpp @@ -163,6 +163,8 @@ void merge(NamespaceInfo& I, NamespaceInfo&& Other) I.specs.raw.value |= Other.specs.raw.value; mergeScopeInfo(I, std::move(Other)); mergeInfo(I, std::move(Other)); + reduceSymbolIDs(I.UsingDirectives, + std::move(Other.UsingDirectives)); } void merge(RecordInfo& I, RecordInfo&& Other) diff --git a/src/lib/Support/SafeNames.cpp b/src/lib/Support/SafeNames.cpp index 9a376339b..588b3192b 100644 --- a/src/lib/Support/SafeNames.cpp +++ b/src/lib/Support/SafeNames.cpp @@ -209,8 +209,6 @@ class SafeNames::Impl } if constexpr(T::isUsing()) { - if (t.Class == UsingClass::Namespace) - return getReserved(t); MRDOCS_ASSERT(! t.Name.empty()); return t.Name; }