Skip to content

Commit 691866e

Browse files
committed
Write parsed doc for all decls.
1 parent f729e0d commit 691866e

File tree

3 files changed

+185
-29
lines changed

3 files changed

+185
-29
lines changed

source/slang/hlsl.meta.slang

+70
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,76 @@ __generic<T, let N:int>
363363
vector<T,N+1> __makeVector(vector<T,N> vec, T scalar);
364364

365365
//@public:
366+
/// @internal
367+
/// A parameterized type that represents all flavors of texture types supported by the Slang language.
368+
/// Please note that this type is not intended to be used directly in user code, and not all combinations
369+
/// of the generic arguments are valid.
370+
/// Instead, use the specific texture types such as `Texture1D`, `Texture2DArray` and `Sampler2D` etc.
371+
/// This documentation is provided for reference purposes only.
372+
/// @param T The element type of the texture. Must be a scalar or vector type.
373+
/// @param Shape The shape of the texture. Must be one of `__Shape1D`, `__Shape2D`, `__Shape3D`, `__ShapeCube` or `__ShapeBuffer`.
374+
/// @param isArray Indicates whether the texture is an array texture.
375+
/// @param isMS Indicates whether the texture is a multisampled texture.
376+
/// @param sampleCount The number of samples of a multisampled texture.
377+
/// @param access The access mode of the texture. 0 for read-only, 1 for read-write, 2 for rasterizer-ordered, 3 for feedback.
378+
/// @param isShadow Indicates whether the texture is a shadow texture (for combined texture-sampler only).
379+
/// @param isCombined Indicates whether the texture is a combined texture-sampler.
380+
/// @param format The storage format of the texture. Users should specify the format using an `[format("...")]` attribute instead.
381+
/// @see `Texture1D`, `Texture2D`, `Texture3D`, `TextureCube`, `Texture1DArray`,
382+
/// `Texture2DArray`, `TextureCubeArray`, `Sampler1D`, `Sampler2D`, `Sampler3D`, `SamplerCube`, `Sampler1DArray`, `Sampler2DArray`, `SamplerCubeArray`,
383+
/// `Texture2DMS`, `Texture2DMSArray`, `RWTexture1D`, `RWTexture2D`, `RWTexture3D`, `RWTexture1DArray`, `RWTexture2DArray`,
384+
/// `RWTexture2DMS`, `RWTexture2DMSArray`, `RWTextureBuffer`, `FeedbackTexture2D`, `FeedbackTexture2DArray`.
385+
/// @remarks
386+
/// HLSL texture types are implemented as typealiases to the builtin `_Texture` type. Users
387+
/// are advised to use the HLSL-specific texture types instead of `_Texture` directly.
388+
///
389+
/// For read-write textures, Slang will automatically infer `format` from `T`.
390+
/// To explicitly specify texel storage formats for read-write textures,
391+
/// use the `[format("...")]` attribute on the texture parameter declaration.
392+
/// Allowed `format` values are:
393+
/// |id | Format string | Meaning |
394+
/// |:--|:---------------------|:------------------|
395+
/// |1 |`"rgba32f"` | 4 channel 32-bit floating point texture |
396+
/// |2 |`"rgba16f"` | 4 channel 16-bit floating point texture |
397+
/// |3 |`"rg32f"` | 2 channel 32-bit floating point texture |
398+
/// |4 |`"rg16f"` | 2 channel 16-bit floating point texture |
399+
/// |5 |`"r11f_g11f_b10f"` | 3 channel 11/11/10-bit floating point texture |
400+
/// |6 |`"r32f"` | 1 channel 32-bit floating point texture |
401+
/// |7 |`"r16f"` | 1 channel 16-bit floating point texture |
402+
/// |8 |`"rgba16"` | 4 channel 16-bit normalized unsigned integer texture |
403+
/// |9 |`"rgb10_a2"` | 4 channel 10/10/10/2-bit signed integer texture |
404+
/// |10 |`"rgba8"` | 4 channel 8-bit normalized unsigned integer texture |
405+
/// |11 |`"rg16"` | 2 channel 16-bit normalized unsigned integer texture |
406+
/// |12 |`"rg8"` | 2 channel 8-bit normalized unsigned integer texture |
407+
/// |13 |`"r16"` | 1 channel 16-bit normalized unsigned integer texture |
408+
/// |14 |`"r8"` | 1 channel 8-bit normalized unsigned integer texture |
409+
/// |15 |`"rgba16_snorm"` | 4 channel 16-bit normalized signed integer texture |
410+
/// |16 |`"rgba8_snorm"` | 4 channel 8-bit normalized signed integer texture |
411+
/// |17 |`"rg16_snorm"` | 2 channel 16-bit normalized signed integer texture |
412+
/// |18 |`"rg8_snorm"` | 2 channel 8-bit normalized signed integer texture |
413+
/// |19 |`"r16_snorm"` | 1 channel 16-bit normalized signed integer texture |
414+
/// |20 |`"r8_snorm"` | 1 channel 8-bit normalized signed integer texture |
415+
/// |21 |`"rgba32i"` | 4 channel 32-bit signed integer texture |
416+
/// |22 |`"rgba16i"` | 4 channel 16-bit signed integer texture |
417+
/// |23 |`"rgba8i"` | 4 channel 8-bit signed integer texture |
418+
/// |24 |`"rg32i"` | 2 channel 32-bit signed integer texture |
419+
/// |25 |`"rg16i"` | 2 channel 16-bit signed integer texture |
420+
/// |26 |`"rg8i"` | 2 channel 8-bit signed integer texture |
421+
/// |27 |`"r32i"` | 1 channel 32-bit signed integer texture |
422+
/// |28 |`"r16i"` | 1 channel 16-bit signed integer texture |
423+
/// |29 |`"r8i"` | 1 channel 8-bit signed integer texture |
424+
/// |30 |`"rgba32ui"` | 4 channel 32-bit unsigned integer texture |
425+
/// |31 |`"rgba16ui"` | 4 channel 16-bit unsigned integer texture |
426+
/// |32 |`"rgb10_a2ui"` | 4 channel 10/10/10/2-bit unsigned integer texture |
427+
/// |33 |`"rgba8ui"` | 4 channel 8-bit unsigned integer texture |
428+
/// |34 |`"rg32ui"` | 2 channel 32-bit unsigned integer texture |
429+
/// |35 |`"rg16ui"` | 2 channel 16-bit unsigned integer texture |
430+
/// |36 |`"rg8ui"` | 2 channel 8-bit unsigned integer texture |
431+
/// |37 |`"r32ui"` | 1 channel 32-bit unsigned integer texture |
432+
/// |38 |`"r16ui"` | 1 channel 16-bit unsigned integer texture |
433+
/// |39 |`"r8ui"` | 1 channel 8-bit unsigned integer texture |
434+
/// |40 |`"r64ui"` | 1 channel 64-bit unsigned integer texture |
435+
/// |41 |`"r64i"` | 1 channel 64-bit signed integer texture |
366436
__magic_type(TextureType)
367437
__intrinsic_type($(kIROp_TextureType))
368438
struct _Texture<T, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let access:int, let isShadow:int, let isCombined:int, let format:int>

source/slang/slang-doc-markdown-writer.cpp

+108-26
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,11 @@ void DocMarkdownWriter::writeVar(const ASTMarkup::Entry& entry, VarDecl* varDecl
448448

449449
out << toSlice("# ") << printer.getSlice() << toSlice("\n\n");
450450

451+
DeclDocumentation declDoc;
452+
declDoc.parse(entry.m_markup.getUnownedSlice());
453+
declDoc.writeDescription(out, this, varDecl);
454+
455+
out << toSlice("## Signature\n");
451456
out << toSlice("<pre>\n");
452457
if (varDecl->hasModifier<HLSLStaticModifier>())
453458
{
@@ -482,7 +487,9 @@ void DocMarkdownWriter::writeVar(const ASTMarkup::Entry& entry, VarDecl* varDecl
482487

483488
out << toSlice(";\n</pre>\n\n");
484489

485-
writeDescription(entry);
490+
declDoc.writeSection(out, this, varDecl, DocPageSection::Remarks);
491+
declDoc.writeSection(out, this, varDecl, DocPageSection::Example);
492+
declDoc.writeSection(out, this, varDecl, DocPageSection::SeeAlso);
486493
}
487494

488495
void DocMarkdownWriter::writeProperty(const ASTMarkup::Entry& entry, PropertyDecl* propertyDecl)
@@ -494,7 +501,11 @@ void DocMarkdownWriter::writeProperty(const ASTMarkup::Entry& entry, PropertyDec
494501
printer.addDeclPath(DeclRef<Decl>(propertyDecl));
495502
out << escapeMarkdownText(printer.getSlice()) << toSlice("\n\n");
496503

497-
out << toSlice("## Definition\n\n");
504+
DeclDocumentation declDoc;
505+
declDoc.parse(entry.m_markup.getUnownedSlice());
506+
declDoc.writeDescription(out, this, propertyDecl);
507+
508+
out << toSlice("## Signature\n\n");
498509

499510
out << toSlice("<pre>\n<span class='code_keyword'>property</span> ");
500511
out << translateToHTMLWithLinks(printer.getSlice());
@@ -520,7 +531,10 @@ void DocMarkdownWriter::writeProperty(const ASTMarkup::Entry& entry, PropertyDec
520531
}
521532
out << "}\n</pre>\n\n";
522533

523-
writeDescription(entry);
534+
declDoc.writeSection(out, this, propertyDecl, DocPageSection::ReturnInfo);
535+
declDoc.writeSection(out, this, propertyDecl, DocPageSection::Remarks);
536+
declDoc.writeSection(out, this, propertyDecl, DocPageSection::Example);
537+
declDoc.writeSection(out, this, propertyDecl, DocPageSection::SeeAlso);
524538
}
525539

526540
void DocMarkdownWriter::writeTypeDef(const ASTMarkup::Entry& entry, TypeDefDecl* typeDefDecl)
@@ -532,7 +546,11 @@ void DocMarkdownWriter::writeTypeDef(const ASTMarkup::Entry& entry, TypeDefDecl*
532546
_appendAggTypeName(newEntry, typeDefDecl);
533547
out << toSlice("\n\n");
534548

535-
out << toSlice("## Definition\n\n");
549+
DeclDocumentation declDoc;
550+
declDoc.parse(entry.m_markup.getUnownedSlice());
551+
declDoc.writeDescription(out, this, typeDefDecl);
552+
553+
out << toSlice("## Signature\n\n");
536554

537555
out << toSlice("<pre>\n<span class='code_keyword'>typealias</span> ");
538556
ASTPrinter printer(m_astBuilder);
@@ -548,7 +566,9 @@ void DocMarkdownWriter::writeTypeDef(const ASTMarkup::Entry& entry, TypeDefDecl*
548566
out << translateToHTMLWithLinks(typeDefDecl->type->toString());
549567
out << ";\n</pre>\n\n";
550568

551-
writeDescription(entry);
569+
declDoc.writeSection(out, this, typeDefDecl, DocPageSection::Remarks);
570+
declDoc.writeSection(out, this, typeDefDecl, DocPageSection::Example);
571+
declDoc.writeSection(out, this, typeDefDecl, DocPageSection::SeeAlso);
552572
}
553573

554574
void DocMarkdownWriter::writeExtensionConditions(StringBuilder& out, ExtensionDecl* extensionDecl, const char* prefix, bool isHtml)
@@ -777,7 +797,7 @@ void DocMarkdownWriter::writeSignature(CallableDecl* callableDecl)
777797
out << ";\n";
778798
}
779799

780-
List<DocMarkdownWriter::NameAndText> DocMarkdownWriter::_getUniqueParams(const List<Decl*>& decls, FuncDocumentation* funcDoc)
800+
List<DocMarkdownWriter::NameAndText> DocMarkdownWriter::_getUniqueParams(const List<Decl*>& decls, DeclDocumentation* funcDoc)
781801
{
782802
List<NameAndText> out;
783803

@@ -1101,7 +1121,7 @@ void ParsedDescription::parse(UnownedStringSlice text)
11011121
}
11021122
}
11031123

1104-
void FuncDocumentation::parse(const UnownedStringSlice& text)
1124+
void DeclDocumentation::parse(const UnownedStringSlice& text)
11051125
{
11061126
List<UnownedStringSlice> lines;
11071127
StringUtil::calcLines(text, lines);
@@ -1176,6 +1196,21 @@ void FuncDocumentation::parse(const UnownedStringSlice& text)
11761196
currentSection = DocPageSection::SeeAlso;
11771197
line = line.tail(4).trim();
11781198
}
1199+
else if (line.startsWith("@experimental"))
1200+
{
1201+
currentSection = DocPageSection::ExperimentalCallout;
1202+
line = line.tail(13).trim();
1203+
}
1204+
else if (line.startsWith("@internal"))
1205+
{
1206+
currentSection = DocPageSection::InternalCallout;
1207+
line = line.tail(9).trim();
1208+
}
1209+
else if (line.startsWith("@deprecated"))
1210+
{
1211+
currentSection = DocPageSection::InternalCallout;
1212+
line = line.tail(11).trim();
1213+
}
11791214
sectionBuilders[currentSection] << line << "\n";
11801215
}
11811216
for (auto& kv : sectionBuilders)
@@ -1224,7 +1259,7 @@ void DocMarkdownWriter::writeCallableOverridable(DocumentPage* page, const ASTMa
12241259
}
12251260
}
12261261

1227-
FuncDocumentation funcDoc;
1262+
DeclDocumentation funcDoc;
12281263
funcDoc.parse(descriptionSB.getUnownedSlice());
12291264
funcDoc.parse(additionalDescriptionSB.getUnownedSlice());
12301265

@@ -1402,11 +1437,17 @@ void DocMarkdownWriter::writeEnum(const ASTMarkup::Entry& entry, EnumDecl* enumD
14021437
}
14031438
out << toSlice("\n\n");
14041439

1440+
DeclDocumentation declDoc;
1441+
declDoc.parse(entry.m_markup.getUnownedSlice());
1442+
declDoc.writeDescription(out, this, enumDecl);
1443+
14051444
out << toSlice("## Values \n\n");
14061445

14071446
_appendAsBullets(_getAsNameAndTextList(enumDecl->getMembersOfType<EnumCaseDecl>()), false, '_');
14081447

1409-
writeDescription(entry);
1448+
declDoc.writeSection(out, this, enumDecl, DocPageSection::Remarks);
1449+
declDoc.writeSection(out, this, enumDecl, DocPageSection::Example);
1450+
declDoc.writeSection(out, this, enumDecl, DocPageSection::SeeAlso);
14101451
}
14111452

14121453
void DocMarkdownWriter::_appendEscaped(const UnownedStringSlice& text)
@@ -1589,7 +1630,10 @@ void DocMarkdownWriter::writeAggType(DocumentPage* page, const ASTMarkup::Entry&
15891630
}
15901631
}
15911632

1592-
writeDescription(primaryEntry);
1633+
DeclDocumentation declDoc;
1634+
declDoc.parse(primaryEntry.m_markup.getUnownedSlice());
1635+
declDoc.writeDescription(out, this, aggTypeDecl);
1636+
15931637
if (GenericDecl* genericDecl = as<GenericDecl>(aggTypeDecl->parentDecl))
15941638
{
15951639
// The parameters, in order
@@ -1754,6 +1798,9 @@ void DocMarkdownWriter::writeAggType(DocumentPage* page, const ASTMarkup::Entry&
17541798
}
17551799
}
17561800
}
1801+
declDoc.writeSection(out, this, aggTypeDecl, DocPageSection::Remarks);
1802+
declDoc.writeSection(out, this, aggTypeDecl, DocPageSection::Example);
1803+
declDoc.writeSection(out, this, aggTypeDecl, DocPageSection::SeeAlso);
17571804
}
17581805

17591806
String DocMarkdownWriter::escapeMarkdownText(String text)
@@ -1981,26 +2028,61 @@ void DocMarkdownWriter::writePreamble()
19812028
}
19822029
}
19832030

1984-
bool DocMarkdownWriter::writeDescription(const ASTMarkup::Entry& entry)
2031+
const char* getSectionTitle(DocPageSection section)
19852032
{
1986-
auto& out = *m_builder;
1987-
1988-
if (entry.m_markup.trim().getLength() > 0)
2033+
switch (section)
19892034
{
1990-
out << toSlice("## Description\n\n");
2035+
case DocPageSection::Description: return "Description";
2036+
case DocPageSection::Parameter: return "Parameters";
2037+
case DocPageSection::ReturnInfo: return "Return value";
2038+
case DocPageSection::Remarks: return "Remarks";
2039+
case DocPageSection::Example: return "Example";
2040+
case DocPageSection::SeeAlso: return "See also";
2041+
default: return "";
2042+
}
2043+
}
19912044

1992-
out << entry.m_markup.getUnownedSlice();
1993-
#if 0
1994-
UnownedStringSlice text(entry.m_markup.getUnownedSlice()), line;
1995-
while (StringUtil::extractLine(text, line))
1996-
{
1997-
out << line << toSlice("\n");
1998-
}
1999-
#endif
2000-
out << toSlice("\n");
2001-
return true;
2045+
void DeclDocumentation::writeDescription(StringBuilder& out, DocMarkdownWriter* writer, Decl* decl)
2046+
{
2047+
// Write all callout sections first.
2048+
writeSection(out, writer, decl, DocPageSection::DeprecatedCallout);
2049+
writeSection(out, writer, decl, DocPageSection::ExperimentalCallout);
2050+
writeSection(out, writer, decl, DocPageSection::InternalCallout);
2051+
2052+
// Write description section.
2053+
writeSection(out, writer, decl, DocPageSection::Description);
2054+
}
2055+
2056+
void DeclDocumentation::writeSection(StringBuilder& out, DocMarkdownWriter* writer, Decl* decl, DocPageSection section)
2057+
{
2058+
SLANG_UNUSED(decl);
2059+
ParsedDescription* sectionDoc = sections.tryGetValue(section);
2060+
if (!sectionDoc)
2061+
return;
2062+
2063+
switch (section)
2064+
{
2065+
case DocPageSection::DeprecatedCallout:
2066+
out << "> #### Deprecated Feature\n";
2067+
out << "> The feature described in this page is marked as deprecated, and may be removed in a future release.\n";
2068+
out << "> Users are advised to avoid using this feature, and to migrate to a newer alternative.\n";
2069+
return;
2070+
case DocPageSection::ExperimentalCallout:
2071+
out << "> #### Experimental Feature\n";
2072+
out << "> The feature described in this page is marked as experimental, and may be subject to change in future releases.\n";
2073+
out << "> Users are advised that any code that depend on this feature may not be compilable by future versions of the compiler.\n";
2074+
return;
2075+
case DocPageSection::InternalCallout:
2076+
out << "> #### Internal Feature\n";
2077+
out << "> The feature described in this page is marked as an internal implementation detail, and is not intended for use by end-users.\n";
2078+
out << "> Users are advised to avoid using this declaration directly, as it may be removed or changed in future releases.\n";
2079+
return;
2080+
}
2081+
if (sectionDoc && sectionDoc->ownedText.getLength() > 0)
2082+
{
2083+
out << "## \"" << getSectionTitle(section) << "\n\n";
2084+
sectionDoc->write(writer, out);
20022085
}
2003-
return false;
20042086
}
20052087

20062088
void DocMarkdownWriter::createPage(DocMarkdownWriter::WriteDeclMode mode, ASTMarkup::Entry& entry, Decl* decl)

source/slang/slang-doc-markdown-writer.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,18 @@ enum class DocPageSection
7575
Remarks,
7676
Example,
7777
SeeAlso,
78+
InternalCallout,
79+
ExperimentalCallout,
80+
DeprecatedCallout,
7881
};
7982

80-
struct FuncDocumentation
83+
struct DeclDocumentation
8184
{
8285
Dictionary<String, ParamDocumentation> parameters;
8386
Dictionary<DocPageSection, ParsedDescription> sections;
8487
void parse(const UnownedStringSlice& text);
88+
void writeDescription(StringBuilder& out, DocMarkdownWriter* writer, Decl* decl);
89+
void writeSection(StringBuilder& sb, DocMarkdownWriter* writer, Decl* decl, DocPageSection section);
8590
};
8691

8792
struct DocMarkdownWriter
@@ -142,7 +147,6 @@ struct DocMarkdownWriter
142147
void createPage(WriteDeclMode mode, ASTMarkup::Entry& entry, Decl* decl);
143148

144149
void writePreamble();
145-
bool writeDescription(const ASTMarkup::Entry& entry);
146150

147151
void writeSignature(CallableDecl* callableDecl);
148152
void writeExtensionConditions(StringBuilder& sb, ExtensionDecl* decl, const char* prefix, bool isHtml);
@@ -179,7 +183,7 @@ struct DocMarkdownWriter
179183
String text;
180184
};
181185

182-
List<NameAndText> _getUniqueParams(const List<Decl*>& decls, FuncDocumentation* funcDoc);
186+
List<NameAndText> _getUniqueParams(const List<Decl*>& decls, DeclDocumentation* funcDoc);
183187

184188
String _getName(Decl* decl);
185189
String _getFullName(Decl* decl);

0 commit comments

Comments
 (0)