// slang-doc-markdown-writer.h #ifndef SLANG_DOC_MARKDOWN_WRITER_H #define SLANG_DOC_MARKDOWN_WRITER_H #include "slang-doc-extractor.h" #include "slang-ast-print.h" #include "slang-compiler.h" namespace Slang { class ASTBuilder; struct DocMarkdownWriter { typedef ASTPrinter::Part Part; typedef ASTPrinter::PartPair PartPair; struct Signature { struct GenericParam { Part name; Part type; }; Part returnType; List params; List genericParams; Part name; }; struct Requirement { typedef Requirement ThisType; bool operator<(const ThisType& rhs) const { return Index(target) < Index(rhs.target) || (target == rhs.target && value < rhs.value); } bool operator==(const ThisType& rhs) const { return target == rhs.target && value == rhs.value; } SLANG_FORCE_INLINE bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } /// Using CodeGenTarget may not be most appropriate, perhaps it should use a CapabilityAtom /// For now use target, and since we always go through Source -> byte code it is fairly straight forward to understand the /// meaning. CodeGenTarget target; /// The 'value' requirement associated with a target. If it's empty it's just the target that is a requirement. String value; }; /// Write out all documentation to the output buffer void writeAll(); /// This will write information about *all* of the overridden versions of a function/method void writeCallableOverridable(const DocMarkup::Entry& entry, CallableDecl* callable); void writeEnum(const DocMarkup::Entry& entry, EnumDecl* enumDecl); void writeAggType(const DocMarkup::Entry& entry, AggTypeDeclBase* aggTypeDecl); void writeDecl(const DocMarkup::Entry& entry, Decl* decl); void writeVar(const DocMarkup::Entry& entry, VarDecl* varDecl); void writePreamble(const DocMarkup::Entry& entry); void writeDescription(const DocMarkup::Entry& entry); void writeSignature(CallableDecl* callableDecl); bool isVisible(const DocMarkup::Entry& entry); bool isVisible(Decl* decl); bool isVisible(const Name* name); /// Get the output string const StringBuilder& getOutput() const { return m_builder; } /// Ctor. DocMarkdownWriter(DocMarkup* markup, ASTBuilder* astBuilder) : m_markup(markup), m_astBuilder(astBuilder) { } struct StringListSet; /// Given a list of ASTPrinter::Parts, works out the different parts of the sig static void getSignature(const List& parts, Signature& outSig); struct NameAndText { String name; String text; }; List _getUniqueParams(const List& decls); String _getName(Decl* decl); String _getName(InheritanceDecl* decl); NameAndText _getNameAndText(DocMarkup::Entry* entry, Decl* decl); NameAndText _getNameAndText(Decl* decl); template List _getAsNameAndTextList(const FilteredMemberList& in) { List out; for (auto decl : const_cast&>(in)) { out.add(_getNameAndText(decl)); } return out; } template List _getAsStringList(const List& in) { List strings; for (auto decl : in) { strings.add(_getName(decl)); } return strings; } List _getAsNameAndTextList(const List& in); List _getAsStringList(const List& in); void _appendAsBullets(const List& values, char wrapChar); void _appendAsBullets(const List& values, char wrapChar); void _appendCommaList(const List& strings, char wrapChar); void _appendRequirements(const List& requirements); void _maybeAppendRequirements(const UnownedStringSlice& title, const List>& uniqueRequirements); void _writeTargetRequirements(const Requirement* reqs, Index reqsCount); /// Appends prefix and the list of types derived from void _appendDerivedFrom(const UnownedStringSlice& prefix, AggTypeDeclBase* aggTypeDecl); void _appendEscaped(const UnownedStringSlice& text); void _appendAggTypeName(AggTypeDeclBase* aggTypeDecl); DocMarkup* m_markup; ASTBuilder* m_astBuilder; StringBuilder m_builder; }; } // namespace Slang #endif