summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-03-15 12:48:20 -0400
committerGitHub <noreply@github.com>2021-03-15 09:48:20 -0700
commitb6de9a0091ab6a7414b46c7eb50f25b9512fb455 (patch)
treeadc37f1942d848446182f0dbb72dd1f487dbb587
parentd8150e70612b58fb1cfefa262d3d862a6e6e79ba (diff)
Test Doc System (#1754)
* #include an absolute path didn't work - because paths were taken to always be relative. * Use capability system in docs. Simplify how requirements/availability is produced. * Small fixes in output of availablity. * Updated stdlib doc. * Small improvements. * Added doc test type. Improved readability of straight .md text Made -doc option output to diagnostic stream. * Add test for checking requirements info is correctly extracted. Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
-rw-r--r--source/slang/slang-doc-markdown-writer.cpp13
-rw-r--r--source/slang/slang.cpp28
-rw-r--r--tests/doc/doc-req.slang15
-rw-r--r--tests/doc/doc-req.slang.expected18
-rw-r--r--tests/doc/doc.slang2
-rw-r--r--tests/doc/doc.slang.expected375
-rw-r--r--tools/slang-test/slang-test-main.cpp66
7 files changed, 496 insertions, 21 deletions
diff --git a/source/slang/slang-doc-markdown-writer.cpp b/source/slang/slang-doc-markdown-writer.cpp
index 5105b0b26..c2bc05dbb 100644
--- a/source/slang/slang-doc-markdown-writer.cpp
+++ b/source/slang/slang-doc-markdown-writer.cpp
@@ -830,6 +830,8 @@ void DocMarkdownWriter::writeCallableOverridable(const DocMarkup::Entry& entry,
_appendAsBullets(_getUniqueParams(genericDecls), '`');
// And parameters
_appendAsBullets(_getUniqueParams(paramDecls), '`');
+
+ out << toSlice("\n");
}
}
}
@@ -1034,8 +1036,9 @@ void DocMarkdownWriter::writeAggType(const DocMarkup::Entry& entry, AggTypeDeclB
if (params.getCount())
{
- out << "## Generic Parameters\n\n";
+ out << toSlice("## Generic Parameters\n\n");
_appendAsBullets(_getAsNameAndTextList(params), '`');
+ out << toSlice("\n");
}
}
@@ -1044,9 +1047,9 @@ void DocMarkdownWriter::writeAggType(const DocMarkup::Entry& entry, AggTypeDeclB
_getDeclsOfType<VarDecl>(aggTypeDecl, fields);
if (fields.getCount())
{
- out << "## Fields\n\n";
-
+ out << toSlice("## Fields\n\n");
_appendAsBullets(_getAsNameAndTextList(fields), '`');
+ out << toSlice("\n");
}
}
@@ -1072,6 +1075,7 @@ void DocMarkdownWriter::writeAggType(const DocMarkup::Entry& entry, AggTypeDeclB
out << "## Methods\n\n";
_appendAsBullets(_getAsStringList(uniqueMethods), '`');
+ out << toSlice("\n");
}
}
}
@@ -1081,7 +1085,8 @@ void DocMarkdownWriter::writePreamble(const DocMarkup::Entry& entry)
SLANG_UNUSED(entry);
auto& out = m_builder;
- out << toSlice("\n");
+ //out << toSlice("\n");
+
out.appendRepeatedChar('-', 80);
out << toSlice("\n");
}
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index ae3a1f419..93d7be310 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1843,26 +1843,22 @@ SlangResult FrontEndCompileRequest::executeActionsInner()
// cause any problems with scoping
ASTBuilder* astBuilder = getLinkage()->getASTBuilder();
- for (TranslationUnitRequest* translationUnit : translationUnits)
- {
- RefPtr<DocMarkup> markup(new DocMarkup);
- DocMarkupExtractor::extract(translationUnit->getModuleDecl(), getSourceManager(), getSink(), markup);
+ ISlangWriter* writer = getSink()->writer;
- // Hmm.. we can have multiple sourcefiles. So fir now we just pick the first, so as to come up with
- // a reasonable name
- SourceFile* sourceFile = translationUnit->getSourceFiles()[0];
-
- // Extract to a file
- const String& path = sourceFile->getPathInfo().foundPath;
- if (path.getLength())
+ // Write output to the diagnostic writer
+ if (writer)
+ {
+ for (TranslationUnitRequest* translationUnit : translationUnits)
{
- String fileName = Path::getFileNameWithoutExt(path);
- fileName.append(".md");
+ RefPtr<DocMarkup> markup(new DocMarkup);
+ DocMarkupExtractor::extract(translationUnit->getModuleDecl(), getSourceManager(), getSink(), markup);
- DocMarkdownWriter writer(markup, astBuilder);
- writer.writeAll();
+ // Convert to markdown
+ DocMarkdownWriter markdownWriter(markup, astBuilder);
+ markdownWriter.writeAll();
- File::writeAllText(fileName, writer.getOutput());
+ UnownedStringSlice docText = markdownWriter.getOutput().getUnownedSlice();
+ writer->write(docText.begin(), docText.getLength());
}
}
}
diff --git a/tests/doc/doc-req.slang b/tests/doc/doc-req.slang
new file mode 100644
index 000000000..bee11f7d4
--- /dev/null
+++ b/tests/doc/doc-req.slang
@@ -0,0 +1,15 @@
+//TEST:DOC:-module-name module -doc -no-codegen
+
+// To Test out documentation around intrinsics
+
+__target_intrinsic(hlsl, "someHLSLThing()")
+[__requiresNVAPI]
+__cuda_sm_version(2.0)
+__target_intrinsic(cuda, "someCUDAThing()")
+__target_intrinsic(glsl, "someGLSLThing()")
+__glsl_extension(GL_EXT_NiftyExtension)
+__spirv_version(1.3)
+__target_intrinsic(cpp, "someCPPThing()")
+void doThing()
+{
+}
diff --git a/tests/doc/doc-req.slang.expected b/tests/doc/doc-req.slang.expected
new file mode 100644
index 000000000..51421cdc7
--- /dev/null
+++ b/tests/doc/doc-req.slang.expected
@@ -0,0 +1,18 @@
+result code = 0
+standard error = {
+--------------------------------------------------------------------------------
+# `doThing`
+
+## Signature
+
+```
+void doThing();
+```
+
+## Availability
+
+**GLSL** `GL_EXT_NiftyExtension`, `SPIR-V 1.3` **HLSL** `NVAPI` **CPP** **CUDA** `SM 2.0`
+
+}
+standard output = {
+}
diff --git a/tests/doc/doc.slang b/tests/doc/doc.slang
index 447b6f6f3..1e04171a0 100644
--- a/tests/doc/doc.slang
+++ b/tests/doc/doc.slang
@@ -1,4 +1,4 @@
-//DISABLE_TEST:SIMPLE:-entry computeMain -target spirv -stage compute -doc
+//TEST:DOC:-entry computeMain -target hlsl -stage compute -doc -no-codegen
void outFunc(out int v)
{
diff --git a/tests/doc/doc.slang.expected b/tests/doc/doc.slang.expected
new file mode 100644
index 000000000..95b3381b5
--- /dev/null
+++ b/tests/doc/doc.slang.expected
@@ -0,0 +1,375 @@
+result code = 0
+standard error = {
+--------------------------------------------------------------------------------
+# `outFunc`
+
+## Signature
+
+```
+void outFunc(out int v);
+```
+
+## Parameters
+
+* `v`
+
+--------------------------------------------------------------------------------
+# `struct ParentStruct<T>`
+
+## Description
+
+Testing out nested generics
+
+## Generic Parameters
+
+* `T` Some type
+
+--------------------------------------------------------------------------------
+# `struct ParentStruct<T>.ChildStruct<S>`
+
+## Description
+
+Testing out a child
+
+## Generic Parameters
+
+* `S` Some other type
+
+## Methods
+
+* `getValue`
+
+--------------------------------------------------------------------------------
+# `ParentStruct<T>.ChildStruct<S>.getValue`
+
+## Description
+
+A useless method hey ho
+
+## Signature
+
+```
+T ParentStruct<T>.ChildStruct<S>.getValue(S v);
+```
+
+## Parameters
+
+* `v`
+
+--------------------------------------------------------------------------------
+# `struct GenericStruct<T>`
+
+## Generic Parameters
+
+* `T`
+
+## Fields
+
+* `value`
+
+## Methods
+
+* `getValue`
+
+--------------------------------------------------------------------------------
+# `GenericStruct<T>.getValue`
+
+## Signature
+
+```
+T GenericStruct<T>.getValue();
+```
+
+--------------------------------------------------------------------------------
+# `addInts`
+
+## Description
+
+A rather silly generic function to test out doc extraction
+
+## Signature
+
+```
+T addInts<T, U:int, V:int>(
+ T z,
+ T b);
+```
+
+## Parameters
+
+* `T` The type we are operating on
+* `U` Just testing out a non type based generic
+* `V` And another one
+* `z` CHECKING!!
+* `b` The B parameter
+
+--------------------------------------------------------------------------------
+# `Hey::doAnotherThing`
+
+## Signature
+
+```
+void Hey::doAnotherThing(int a);
+```
+
+## Parameters
+
+* `a`
+
+--------------------------------------------------------------------------------
+# inputBuffer
+
+```
+RWStructuredBuffer inputBuffer
+```
+
+## Description
+
+Let's test indent
+
+```
+{
+ imIndented();
+}
+```
+
+--------------------------------------------------------------------------------
+# `interface IDoThing`
+
+## Description
+
+An interface to do things
+
+# Associated types
+
+* _V_ An associated type
+
+
+## Methods
+
+* `add`
+* `sub`
+
+--------------------------------------------------------------------------------
+# `IDoThing.add`
+
+## Description
+
+Add two integers
+
+## Signature
+
+```
+V IDoThing.add(
+ V a,
+ V b);
+```
+
+## Parameters
+
+* `a` First parameter
+* `b` Second parameter
+
+--------------------------------------------------------------------------------
+# `IDoThing.sub`
+
+## Description
+
+Subtract
+Multi-line
+
+## Signature
+
+```
+int IDoThing.sub(
+ int a,
+ int b);
+```
+
+## Parameters
+
+* `a` First
+* `b` Second
+
+--------------------------------------------------------------------------------
+# `interface IThing`
+
+## Methods
+
+* `getValue`
+
+--------------------------------------------------------------------------------
+# `IThing.getValue`
+
+## Signature
+
+```
+float IThing.getValue();
+```
+
+--------------------------------------------------------------------------------
+# `extension float : IThing`
+
+*Implements:* `IThing`
+
+## Description
+
+Implement IThing on float
+
+## Methods
+
+* `getValue`
+
+--------------------------------------------------------------------------------
+# `float.getValue`
+
+## Description
+
+Just return the float itself!
+
+## Signature
+
+```
+float float.getValue();
+```
+
+--------------------------------------------------------------------------------
+# `struct Thing`
+
+*Implements:* `IThing`, `IDoThing`
+
+## Methods
+
+* `add`
+* `sub`
+* `getValue`
+
+--------------------------------------------------------------------------------
+# `Thing.add`
+
+## Signature
+
+```
+int Thing.add(
+ int a,
+ int b);
+```
+
+## Parameters
+
+* `a`
+* `b`
+
+--------------------------------------------------------------------------------
+# `Thing.sub`
+
+## Signature
+
+```
+int Thing.sub(
+ int a,
+ int b);
+```
+
+## Parameters
+
+* `a`
+* `b`
+
+--------------------------------------------------------------------------------
+# `Thing.getValue`
+
+## Signature
+
+```
+float Thing.getValue();
+```
+
+--------------------------------------------------------------------------------
+# `struct SomeStruct`
+
+## Description
+
+A struct with some fields
+
+## Fields
+
+* `aField` A field
+* `anotherField` Multi-line is a thing
+* `yetAnother` A field with stuff
+
+## Methods
+
+* `getMethod`
+
+--------------------------------------------------------------------------------
+# `SomeStruct.getMethod`
+
+## Description
+
+Get a value
+
+## Signature
+
+```
+int SomeStruct.getMethod();
+```
+
+--------------------------------------------------------------------------------
+# enum AnEnum
+
+## Values
+
+* _Value_ A value
+* _AnotherValue_ Another value With a multi-line comment
+## Description
+
+An enum
+
+--------------------------------------------------------------------------------
+# outputBuffer
+
+```
+RWStructuredBuffer outputBuffer
+```
+
+## Description
+
+An output buffer
+
+--------------------------------------------------------------------------------
+# `doThing`
+
+## Description
+
+doThing!
+
+## Signature
+
+```
+int doThing(
+ int a,
+ int b);
+```
+
+## Parameters
+
+* `a` a parameter
+* `b` b parameter
+
+--------------------------------------------------------------------------------
+# `computeMain`
+
+## Signature
+
+```
+void computeMain(vector<uint,3> dispatchThreadID);
+```
+
+## Parameters
+
+* `dispatchThreadID`
+
+}
+standard output = {
+}
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp
index b49dedd2d..8586ed108 100644
--- a/tools/slang-test/slang-test-main.cpp
+++ b/tools/slang-test/slang-test-main.cpp
@@ -1065,6 +1065,71 @@ static bool _areResultsEqual(TestOptions::Type type, const String& a, const Stri
}
}
+TestResult runDocTest(TestContext* context, TestInput& input)
+{
+ // need to execute the stand-alone Slang compiler on the file, and compare its output to what we expect
+ auto outputStem = input.outputStem;
+
+ CommandLine cmdLine;
+ _initSlangCompiler(context, cmdLine);
+
+ cmdLine.addArg(input.filePath);
+
+ for (auto arg : input.testOptions->args)
+ {
+ cmdLine.addArg(arg);
+ }
+
+ ExecuteResult exeRes;
+ TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, input.spawnType, cmdLine, exeRes));
+
+ if (context->isCollectingRequirements())
+ {
+ return TestResult::Pass;
+ }
+
+ String actualOutput = getOutput(exeRes);
+
+ String expectedOutputPath = outputStem + ".expected";
+ String expectedOutput;
+ try
+ {
+ expectedOutput = Slang::File::readAllText(expectedOutputPath);
+ }
+ catch (const Slang::IOException&)
+ {
+ }
+
+ // If no expected output file was found, then we
+ // expect everything to be empty
+ if (expectedOutput.getLength() == 0)
+ {
+ expectedOutput = "result code = 0\nstandard error = {\n}\nstandard output = {\n}\n";
+ }
+
+ TestResult result = TestResult::Pass;
+
+ // Otherwise we compare to the expected output
+ if (!_areResultsEqual(input.testOptions->type, expectedOutput, actualOutput))
+ {
+ context->reporter->dumpOutputDifference(expectedOutput, actualOutput);
+ result = TestResult::Fail;
+ }
+
+ // If the test failed, then we write the actual output to a file
+ // so that we can easily diff it from the command line and
+ // diagnose the problem.
+ if (result == TestResult::Fail)
+ {
+ String actualOutputPath = outputStem + ".actual";
+ Slang::File::writeAllText(actualOutputPath, actualOutput);
+
+ context->reporter->dumpOutputDifference(expectedOutput, actualOutput);
+ }
+
+ return result;
+}
+
TestResult runSimpleTest(TestContext* context, TestInput& input)
{
// need to execute the stand-alone Slang compiler on the file, and compare its output to what we expect
@@ -2740,6 +2805,7 @@ static const TestCommandInfo s_testCommandInfos[] =
{ "CPP_COMPILER_COMPILE", &runCPPCompilerCompile, RenderApiFlag::CPU},
{ "PERFORMANCE_PROFILE", &runPerformanceProfile, 0 },
{ "COMPILE", &runCompile, 0 },
+ { "DOC", &runDocTest, 0 },
};
const TestCommandInfo* _findTestCommandInfoByCommand(const UnownedStringSlice& name)