From 9ffe2f3ef245034a2dae42017a9059dfe4d02647 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 11 Mar 2021 17:56:03 -0500 Subject: MarkDown -> Markdown (#1748) * #include an absolute path didn't work - because paths were taken to always be relative. * MarkDown -> Markdown slang-doc-mark-down -> slang-doc-markdown-writer --- source/slang/slang-doc-mark-down.cpp | 1115 ---------------------------------- 1 file changed, 1115 deletions(-) delete mode 100644 source/slang/slang-doc-mark-down.cpp (limited to 'source/slang/slang-doc-mark-down.cpp') diff --git a/source/slang/slang-doc-mark-down.cpp b/source/slang/slang-doc-mark-down.cpp deleted file mode 100644 index 384759474..000000000 --- a/source/slang/slang-doc-mark-down.cpp +++ /dev/null @@ -1,1115 +0,0 @@ -// slang-doc-mark-down.cpp -#include "slang-doc-mark-down.h" - -#include "../core/slang-string-util.h" - -#include "slang-ast-builder.h" -#include "slang-lookup.h" - -namespace Slang { - - -struct DocMarkDownWriter::StringListSet -{ - Index add(const HashSet& set) - { - // -1 means empty, which we don't explicitly store - Index index = -1; - if (set.Count()) - { - List values; - for (auto& value : set) - { - values.add(value); - } - // Sort so that can be compared for uniqueness - values.sort(); - - index = m_uniqueValues.indexOf(values); - if (index < 0) - { - index = m_uniqueValues.getCount(); - m_uniqueValues.add(values); - } - } - m_map.add(index); - return index; - } - - Index getValueIndex(Index index) const { return m_map[index]; } - List& getValuesAt(Index valueIndex) { return m_uniqueValues[valueIndex]; } - const List>& getUniqueValues() const { return m_uniqueValues; } - - StringListSet() {} - -protected: - List m_map; - List> m_uniqueValues; -}; - -/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DocMarkDownWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ - -template -static void _getDecls(ContainerDecl* containerDecl, List& out) -{ - for (Decl* decl : containerDecl->members) - { - if (T* declAsType = as(decl)) - { - out.add(declAsType); - } - } -} - -template -static void _getDeclsOfType(ContainerDecl* containerDecl, List& out) -{ - for (Decl* decl : containerDecl->members) - { - if (as(decl)) - { - out.add(decl); - } - } -} - -template -static void _toList(FilteredMemberList& list, List& out) -{ - for (Decl* decl : list) - { - out.add(decl); - } -} - -static void _appendAsSingleLine(const UnownedStringSlice& in, StringBuilder& out) -{ - List lines; - StringUtil::calcLines(in, lines); - - // Ideally we'd remove any extraneous whitespace, but for now just join - StringUtil::join(lines.getBuffer(), lines.getCount(), ' ', out); -} - -void DocMarkDownWriter::_appendAsBullets(const List& values, char wrapChar) -{ - auto& out = m_builder; - for (const auto& value : values) - { - out << "* "; - - const String& name = value.name; - if (name.getLength()) - { - if (wrapChar) - { - out.appendChar(wrapChar); - out << name; - out.appendChar(wrapChar); - } - else - { - out << name; - } - } - - if (value.text.getLength()) - { - out.appendChar(' '); - - // Hmm, we'll want to make something multiline into a single line - _appendAsSingleLine(value.text.getUnownedSlice(), out); - } - - out << "\n"; - } -} - -void DocMarkDownWriter::_appendAsBullets(const List& values, char wrapChar) -{ - auto& out = m_builder; - for (const auto& value : values) - { - out << "* "; - - if (value.getLength()) - { - if (wrapChar) - { - out.appendChar(wrapChar); - out << value; - out.appendChar(wrapChar); - - } - else - { - out << value; - } - } - out << "\n"; - } -} - -String DocMarkDownWriter::_getName(Decl* decl) -{ - StringBuilder buf; - ASTPrinter::appendDeclName(decl, buf); - return buf.ProduceString(); -} - -String DocMarkDownWriter::_getName(InheritanceDecl* decl) -{ - StringBuilder buf; - buf.Clear(); - buf << decl->base; - return buf.ProduceString(); -} - -DocMarkDownWriter::NameAndText DocMarkDownWriter::_getNameAndText(DocMarkup::Entry* entry, Decl* decl) -{ - NameAndText nameAndText; - - nameAndText.name = _getName(decl); - - // We could extract different text here, but for now just do all markup - if (entry) - { - // For now we'll just use all markup, but really we need something more sophisticated here - nameAndText.text = entry->m_markup; - } - - return nameAndText; -} - -DocMarkDownWriter::NameAndText DocMarkDownWriter::_getNameAndText(Decl* decl) -{ - DocMarkup::Entry* entry = m_markup->getEntry(decl); - return _getNameAndText(entry, decl); -} - -List DocMarkDownWriter::_getAsNameAndTextList(const List& in) -{ - List out; - for (auto decl : in) - { - out.add(_getNameAndText(decl)); - } - return out; -} - -List DocMarkDownWriter::_getAsStringList(const List& in) -{ - List strings; - for (auto decl : in) - { - strings.add(_getName(decl)); - } - return strings; -} - -void DocMarkDownWriter::_appendCommaList(const List& strings, char wrapChar) -{ - for (Index i = 0; i < strings.getCount(); ++i) - { - if (i > 0) - { - m_builder << toSlice(", "); - } - if (wrapChar) - { - m_builder.appendChar(wrapChar); - m_builder << strings[i]; - m_builder.appendChar(wrapChar); - } - else - { - m_builder << strings[i]; - } - } -} - -/* static */void DocMarkDownWriter::getSignature(const List& parts, Signature& outSig) -{ - const Index count = parts.getCount(); - for (Index i = 0; i < count; ++i) - { - const auto& part = parts[i]; - switch (part.type) - { - case Part::Type::ParamType: - { - PartPair pair; - pair.first = part; - if ((i + 1) < count && parts[i + 1].type == Part::Type::ParamName) - { - pair.second = parts[i + 1]; - i++; - } - outSig.params.add(pair); - break; - } - case Part::Type::ReturnType: - { - outSig.returnType = part; - break; - } - case Part::Type::DeclPath: - { - outSig.name = part; - break; - } - case Part::Type::GenericParamValue: - case Part::Type::GenericParamType: - { - Signature::GenericParam genericParam; - genericParam.name = part; - - if ((i + 1) < count && parts[i + 1].type == Part::Type::GenericParamValueType) - { - genericParam.type = parts[i + 1]; - i++; - } - - outSig.genericParams.add(genericParam); - break; - } - - default: break; - } - } -} - -void DocMarkDownWriter::writeVar(const DocMarkup::Entry& entry, VarDecl* varDecl) -{ - writePreamble(entry); - auto& out = m_builder; - - out << toSlice("# ") << varDecl->getName()->text << toSlice("\n\n"); - - // TODO(JS): The outputting of types this way isn't right - it doesn't handle int a[10] for example. - //ASTPrinter printer(m_astBuilder, ASTPrinter::OptionFlag::ParamNames); - - out << toSlice("```\n"); - out << varDecl->type << toSlice(" ") << varDecl << toSlice("\n"); - out << toSlice("```\n\n"); - - writeDescription(entry); -} - -void DocMarkDownWriter::writeSignature(CallableDecl* callableDecl) -{ - auto& out = m_builder; - - List parts; - - ASTPrinter printer(m_astBuilder, ASTPrinter::OptionFlag::ParamNames, &parts); - printer.addDeclSignature(DeclRef(callableDecl, nullptr)); - - Signature signature; - getSignature(parts, signature); - - const Index paramCount = signature.params.getCount(); - - { - // Some types (like constructors say) don't have any return type, so check before outputting - const UnownedStringSlice returnType = printer.getPartSlice(signature.returnType); - if (returnType.getLength() > 0) - { - out << returnType << toSlice(" "); - } - } - - out << printer.getPartSlice(signature.name); - -#if 0 - if (signature.genericParams.getCount()) - { - out << toSlice("<"); - const Index count = signature.genericParams.getCount(); - for (Index i = 0; i < count; ++i) - { - const auto& genericParam = signature.genericParams[i]; - if (i > 0) - { - out << toSlice(", "); - } - out << printer.getPartSlice(genericParam.name); - - if (genericParam.type.type != Part::Type::None) - { - out << toSlice(" : "); - out << printer.getPartSlice(genericParam.type); - } - } - out << toSlice(">"); - } -#endif - - switch (paramCount) - { - case 0: - { - // Has no parameters - out << toSlice("();\n"); - break; - } - case 1: - { - // Place all on single line - out.appendChar('('); - const auto& param = signature.params[0]; - out << printer.getPartSlice(param.first) << toSlice(" ") << printer.getPartSlice(param.second); - out << ");\n"; - break; - } - default: - { - // Put each parameter on a line on it's own - out << toSlice("(\n"); - StringBuilder line; - for (Index i = 0; i < paramCount; ++i) - { - const auto& param = signature.params[i]; - line.Clear(); - // If we want to tab these over... we'll need to know how must space I have - line << " " << printer.getPartSlice(param.first); - - Index indent = 25; - if (line.getLength() < indent) - { - line.appendRepeatedChar(' ', indent - line.getLength()); - } - else - { - line.appendChar(' '); - } - - line << printer.getPartSlice(param.second); - if (i < paramCount - 1) - { - line << ",\n"; - } - - out << line; - } - - out << ");\n"; - break; - } - } -} - -List DocMarkDownWriter::_getUniqueParams(const List& decls) -{ - List out; - - Dictionary nameDict; - - for (auto decl : decls) - { - Name* name = decl->getName(); - if (!name) - { - continue; - } - - Index index = nameDict.GetOrAddValue(name, out.getCount()); - - if (index >= out.getCount()) - { - out.add(NameAndText{ getText(name), String() }); - } - - NameAndText& nameAndMarkup = out[index]; - if (nameAndMarkup.text.getLength() > 0) - { - continue; - } - - auto entry = m_markup->getEntry(decl); - if (entry && entry->m_markup.getLength()) - { - nameAndMarkup.text = entry->m_markup; - } - } - - return out; -} - -static void _addRequirements(Decl* decl, HashSet& outRequirements) -{ - StringBuilder buf; - - if (auto spirvRequiredModifier = decl->findModifier()) - { - buf.Clear(); - buf << "SPIR-V "; - spirvRequiredModifier->version.append(buf); - outRequirements.Add(buf); - } - - if (auto glslRequiredModifier = decl->findModifier()) - { - buf.Clear(); - buf << "GLSL" << glslRequiredModifier->versionNumberToken.getContent(); - outRequirements.Add(buf); - } - - if (auto cudaSMVersionModifier = decl->findModifier()) - { - buf.Clear(); - buf << "CUDA SM "; - cudaSMVersionModifier->version.append(buf); - outRequirements.Add(buf); - } - - if (auto extensionModifier = decl->findModifier()) - { - buf.Clear(); - buf << "GLSL " << extensionModifier->extensionNameToken.getContent(); - outRequirements.Add(buf); - } - - if (auto requiresNVAPIAttribute = decl->findModifier()) - { - outRequirements.Add("NVAPI"); - } -} - -void DocMarkDownWriter::_maybeAppendSet(const UnownedStringSlice& title, const StringListSet& set) -{ - auto& out = m_builder; - - const auto& uniqueValues = set.getUniqueValues(); - - const Index uniqueCount = uniqueValues.getCount(); - if (uniqueCount > 0 && uniqueValues[0].getCount() > 0) - { - out << title; - if (uniqueCount > 1) - { - for (Index i = 0; i < uniqueCount; ++i) - { - out << (i + 1) << (". "); - _appendCommaList(uniqueValues[i], '`'); - out << toSlice("\n"); - } - } - else - { - _appendCommaList(uniqueValues[0], '`'); - out << toSlice("\n"); - } - out << toSlice("\n"); - } -} - -static Decl* _getSameNameDecl(Decl* decl) -{ - auto parentDecl = decl->parentDecl; - - // Sanity check: there should always be a parent declaration. - // - SLANG_ASSERT(parentDecl); - if (!parentDecl) return nullptr; - - // If the declaration is the "inner" declaration of a generic, - // then we actually want to look one level up, because the - // peers/siblings of the declaration will belong to the same - // parent as the generic, not to the generic. - // - if (auto genericParentDecl = as(parentDecl)) - { - // Note: we need to check here to be sure `newDecl` - // is the "inner" declaration and not one of the - // generic parameters, or else we will end up - // checking them at the wrong scope. - // - if (decl == genericParentDecl->inner) - { - decl = parentDecl; - } - } - - return decl; -} - -static bool _isFirstOverridden(Decl* decl) -{ - decl = _getSameNameDecl(decl); - - ContainerDecl* parentDecl = decl->parentDecl; - - // Make sure we have the member dictionary. - buildMemberDictionary(parentDecl); - - Name* declName = decl->getName(); - if (declName) - { - Decl** firstDeclPtr = parentDecl->memberDictionary.TryGetValue(declName); - return (firstDeclPtr && *firstDeclPtr == decl) || (firstDeclPtr == nullptr); - } - - return false; -} - -void DocMarkDownWriter::writeCallableOverridable(const DocMarkup::Entry& entry, CallableDecl* callableDecl) -{ - auto& out = m_builder; - - writePreamble(entry); - - { - // Output the overridable path (ie without terminal generic parameters) - ASTPrinter printer(m_astBuilder); - printer.addOverridableDeclPath(DeclRef(callableDecl, nullptr)); - // Extract the name - out << toSlice("# `") << printer.getStringBuilder() << toSlice("`\n\n"); - } - - writeDescription(entry); - - List sigs; - { - Decl* sameNameDecl = _getSameNameDecl(callableDecl); - - for (Decl* curDecl = sameNameDecl; curDecl; curDecl = curDecl->nextInContainerWithSameName) - { - CallableDecl* sig = nullptr; - if (GenericDecl* genericDecl = as(curDecl)) - { - sig = as(genericDecl->inner); - } - else - { - sig = as(curDecl); - } - - if (!sig) - { - continue; - } - - // Want to add only the primary sig - if (sig->primaryDecl == nullptr || sig->primaryDecl == sig) - { - sigs.add(sig); - } - } - - // Lets put back into source order - sigs.sort([](CallableDecl* a, CallableDecl* b) -> bool { return a->loc.getRaw() < b->loc.getRaw(); }); - } - - // Set of sets of requirements, holds index map from addition to the set entry - StringListSet requirementsSetSet; - - // Similarly for targets - StringListSet targetSetSet; - - // We want to determine the unique signature, and then the requirements for the signature - { - for (Index i = 0; i < sigs.getCount(); ++i) - { - CallableDecl* sig = sigs[i]; - // Add the requirements for all the different versions - { - HashSet requirementsSet; - HashSet targetSet; - for (CallableDecl* curSig = sig; curSig; curSig = curSig->nextDecl) - { - _addRequirements(sig, requirementsSet); - - // Handle Target info - - for (auto targetIntrinsic : sig->getModifiersOfType()) - { - targetSet.Add(String(targetIntrinsic->targetToken.getContent()).toUpper()); - } - for (auto specializedForTarget : sig->getModifiersOfType()) - { - targetSet.Add(String(specializedForTarget->targetToken.getContent()).toUpper()); - } - } - - requirementsSetSet.add(requirementsSet); - - // TODO(JS): This really isn't right, we ideally have markup that made hlsl availability explicit - // We *assume* that we have 'hlsl' for now - targetSet.Add(String("HLSL")); - targetSetSet.add(targetSet); - } - } - } - - // Output the signature - { - out << toSlice("## Signature \n\n"); - out << toSlice("```\n"); - - Index prevRequirementsIndex = -1; - Index prevTargetIndex = -1; - - const Int sigCount = sigs.getCount(); - for (Index i = 0; i < sigCount; ++i) - { - auto sig = sigs[i]; - - // Output if needs unique requirements - if (requirementsSetSet.getUniqueValues().getCount() > 1) - { - const Index requirementsIndex = requirementsSetSet.getValueIndex(i); - if (requirementsIndex != prevRequirementsIndex) - { - if (requirementsIndex >= 0) - { - out << toSlice("/// See Requirement ") << (requirementsIndex + 1) << toSlice("\n"); - } - else - { - out << toSlice("/// No requirements\n"); - } - prevRequirementsIndex = requirementsIndex; - } - } - - if (targetSetSet.getUniqueValues().getCount() > 1) - { - const Index targetIndex = targetSetSet.getValueIndex(i); - if (targetIndex != prevTargetIndex) - { - if (targetIndex >= 0) - { - out << toSlice("/// See Target Availability ") << (targetIndex + 1) << toSlice("\n"); - } - else - { - out << toSlice("/// All Targets\n"); - } - prevTargetIndex = targetIndex; - } - } - - writeSignature(sig); - } - out << "```\n\n"; - } - - _maybeAppendSet(toSlice("## Requirements\n\n"), requirementsSetSet); - - // Target availability - - { - const auto& uniqueValues = targetSetSet.getUniqueValues(); - if (uniqueValues.getCount() == 1 && uniqueValues[0].getCount() == 1 && uniqueValues[0][0] == "hlsl") - { - // TODO(JS): - // If something is marked up for hlsl, and nothing else, that indicates it might *only* be available on hlsl, but - // we don't correctly handle that here. - - // If the only thing we have is 'hlsl' - we injected that so we'll *assume* it's available everywhere, so - // don't bother outputting. - } - else - { - _maybeAppendSet(toSlice("## Target Availability\n\n"), targetSetSet); - } - } - - { - // We will use the first documentation found for each parameter type - { - List paramDecls; - List genericDecls; - for (auto sig : sigs) - { - GenericDecl* genericDecl = as(sig->parentDecl); - - // NOTE! - // Here we assume the names of generic parameters are such that they are - - // We list generic parameters, as types of parameters, if they are directly associated with this - // callable. - if (genericDecl) - { - for (Decl* decl : genericDecl->members) - { - if (as(decl) || - as(decl)) - { - genericDecls.add(decl); - } - } - } - - for (ParamDecl* paramDecl : sig->getParameters()) - { - paramDecls.add(paramDecl); - } - } - - if (paramDecls.getCount() > 0 || paramDecls.getCount() > 0) - { - out << "## Parameters\n\n"; - - // Get the unique generics - _appendAsBullets(_getUniqueParams(genericDecls), '`'); - // And parameters - _appendAsBullets(_getUniqueParams(paramDecls), '`'); - } - } - } -} - -void DocMarkDownWriter::writeEnum(const DocMarkup::Entry& entry, EnumDecl* enumDecl) -{ - writePreamble(entry); - - auto& out = m_builder; - - out << toSlice("# enum "); - Name* name = enumDecl->getName(); - if (name) - { - out << name->text; - } - out << toSlice("\n\n"); - - out << toSlice("## Values \n\n"); - - _appendAsBullets(_getAsNameAndTextList(enumDecl->getMembersOfType()), '_'); - - writeDescription(entry); -} - -void DocMarkDownWriter::_appendEscaped(const UnownedStringSlice& text) -{ - auto& out = m_builder; - - const char* start = text.begin(); - const char* cur = start; - const char*const end = text.end(); - - for (; cur < end; ++cur) - { - const char c = *cur; - - switch (c) - { - case '<': - case '>': - case '&': - case '"': - case '_': - { - // Flush if any before - if (cur > start) - { - out.append(start, cur); - } - // Prefix with the - out.appendChar('\\'); - - // Start will still include the char, for later flushing - start = cur; - break; - } - default: break; - } - } - - // Flush any remaining - if (cur > start) - { - out.append(start, cur); - } -} - - -void DocMarkDownWriter::_appendDerivedFrom(const UnownedStringSlice& prefix, AggTypeDeclBase* aggTypeDecl) -{ - auto& out = m_builder; - - List inheritanceDecls; - _getDecls(aggTypeDecl, inheritanceDecls); - - const Index count = inheritanceDecls.getCount(); - if (count) - { - out << prefix; - for (Index i = 0; i < count; ++i) - { - InheritanceDecl* inheritanceDecl = inheritanceDecls[i]; - if (i > 0) - { - out << toSlice(", "); - } - out << inheritanceDecl->base; - } - } -} - -void DocMarkDownWriter::_appendAggTypeName(AggTypeDeclBase* aggTypeDecl) -{ - auto& out = m_builder; - - // This could be lots of different things - struct/class/extension/interface/.. - - ASTPrinter printer(m_astBuilder); - printer.addDeclPath(DeclRef(aggTypeDecl, nullptr)); - - if (as(aggTypeDecl)) - { - out << toSlice("struct ") << printer.getStringBuilder(); - } - else if (as(aggTypeDecl)) - { - out << toSlice("class ") << printer.getStringBuilder(); - } - else if (as(aggTypeDecl)) - { - out << toSlice("interface ") << printer.getStringBuilder(); - } - else if (ExtensionDecl* extensionDecl = as(aggTypeDecl)) - { - out << toSlice("extension ") << extensionDecl->targetType; - _appendDerivedFrom(toSlice(" : "), extensionDecl); - } - else - { - out << toSlice("?"); - } -} - -void DocMarkDownWriter::writeAggType(const DocMarkup::Entry& entry, AggTypeDeclBase* aggTypeDecl) -{ - writePreamble(entry); - - auto& out = m_builder; - - // We can write out he name using the printer - - ASTPrinter printer(m_astBuilder); - printer.addDeclPath(DeclRef(aggTypeDecl, nullptr)); - - out << toSlice("# `"); - _appendAggTypeName(aggTypeDecl); - out << toSlice("`\n\n"); - - { - List inheritanceDecls; - _getDecls(aggTypeDecl, inheritanceDecls); - - if (inheritanceDecls.getCount()) - { - out << "*Implements:* "; - _appendCommaList(_getAsStringList(inheritanceDecls), '`'); - out << toSlice("\n\n"); - } - } - - writeDescription(entry); - - { - List assocTypeDecls; - _getDecls(aggTypeDecl, assocTypeDecls); - - if (assocTypeDecls.getCount()) - { - out << toSlice("# Associated types\n\n"); - - for (AssocTypeDecl* assocTypeDecl : assocTypeDecls) - { - out << "* _" << assocTypeDecl->getName()->text << "_ "; - - // Look up markup - DocMarkup::Entry* assocTypeDeclEntry = m_markup->getEntry(assocTypeDecl); - if (assocTypeDeclEntry) - { - _appendAsSingleLine(assocTypeDeclEntry->m_markup.getUnownedSlice(), out); - } - out << toSlice("\n"); - - List inheritanceDecls; - _getDecls(assocTypeDecl, inheritanceDecls); - - if (inheritanceDecls.getCount()) - { - out << " "; - _appendCommaList(_getAsStringList(inheritanceDecls), '`'); - out << toSlice("\n"); - } - } - - out << toSlice("\n\n"); - } - } - - if (GenericDecl* genericDecl = as(aggTypeDecl->parentDecl)) - { - // The parameters, in order - List params; - for (Decl* decl : genericDecl->members) - { - if (as(decl) || - as(decl)) - { - params.add(decl); - } - } - - if (params.getCount()) - { - out << "## Generic Parameters\n\n"; - _appendAsBullets(_getAsNameAndTextList(params), '`'); - } - } - - { - List fields; - _getDeclsOfType(aggTypeDecl, fields); - if (fields.getCount()) - { - out << "## Fields\n\n"; - - _appendAsBullets(_getAsNameAndTextList(fields), '`'); - } - } - - { - // Make sure we've got a query-able member dictionary - buildMemberDictionary(aggTypeDecl); - SLANG_ASSERT(aggTypeDecl->isMemberDictionaryValid()); - - List uniqueMethods; - for (const auto& pair : aggTypeDecl->memberDictionary) - { - CallableDecl* callableDecl = as(pair.Value); - if (callableDecl && isVisible(callableDecl)) - { - uniqueMethods.add(callableDecl); - } - } - - if (uniqueMethods.getCount()) - { - // Put in source definition order - uniqueMethods.sort([](Decl* a, Decl* b) -> bool { return a->loc.getRaw() < b->loc.getRaw(); }); - - out << "## Methods\n\n"; - _appendAsBullets(_getAsStringList(uniqueMethods), '`'); - } - } -} - -void DocMarkDownWriter::writePreamble(const DocMarkup::Entry& entry) -{ - SLANG_UNUSED(entry); - auto& out = m_builder; - - out << toSlice("\n"); - out.appendRepeatedChar('-', 80); - out << toSlice("\n"); -} - -void DocMarkDownWriter::writeDescription(const DocMarkup::Entry& entry) -{ - auto& out = m_builder; - - if (entry.m_markup.getLength() > 0) - { - out << toSlice("## Description\n\n"); - - out << entry.m_markup.getUnownedSlice(); -#if 0 - UnownedStringSlice text(entry.m_markup.getUnownedSlice()), line; - while (StringUtil::extractLine(text, line)) - { - out << line << toSlice("\n"); - } -#endif - out << toSlice("\n"); - } -} - -void DocMarkDownWriter::writeDecl(const DocMarkup::Entry& entry, Decl* decl) -{ - // Skip these they will be output as part of their respective 'containers' - if (as(decl) || as(decl) || as(decl) || as(decl)) - { - return; - } - - if (CallableDecl* callableDecl = as(decl)) - { - if (_isFirstOverridden(callableDecl)) - { - writeCallableOverridable(entry, callableDecl); - } - } - else if (EnumDecl* enumDecl = as(decl)) - { - writeEnum(entry, enumDecl); - } - else if (AggTypeDeclBase* aggType = as(decl)) - { - writeAggType(entry, aggType); - } - else if (VarDecl* varDecl = as(decl)) - { - // If part of aggregate type will be output there. - if (as(varDecl->parentDecl)) - { - return; - } - - writeVar(entry, varDecl); - } - else if (as(decl)) - { - // We can ignore as inner decls will be picked up, and written - } -} - -bool DocMarkDownWriter::isVisible(const Name* name) -{ - return name == nullptr || !name->text.startsWith(toSlice("__")); -} - -bool DocMarkDownWriter::isVisible(const DocMarkup::Entry& entry) -{ - // For now if it's not public it's not visible - if (entry.m_visibility != MarkupVisibility::Public) - { - return false; - } - - Decl* decl = as(entry.m_node); - return decl == nullptr || isVisible(decl->getName()); -} - -bool DocMarkDownWriter::isVisible(Decl* decl) -{ - if (!isVisible(decl->getName())) - { - return false; - } - - auto entry = m_markup->getEntry(decl); - return entry == nullptr || entry->m_visibility == MarkupVisibility::Public; -} - -void DocMarkDownWriter::writeAll() -{ - for (const auto& entry : m_markup->getEntries()) - { - Decl* decl = as(entry.m_node); - - if (decl && isVisible(entry)) - { - writeDecl(entry, decl); - } - } -} - -} // namespace Slang -- cgit v1.2.3