diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-03-15 12:48:20 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-15 09:48:20 -0700 |
| commit | b6de9a0091ab6a7414b46c7eb50f25b9512fb455 (patch) | |
| tree | adc37f1942d848446182f0dbb72dd1f487dbb587 | |
| parent | d8150e70612b58fb1cfefa262d3d862a6e6e79ba (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.cpp | 13 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 28 | ||||
| -rw-r--r-- | tests/doc/doc-req.slang | 15 | ||||
| -rw-r--r-- | tests/doc/doc-req.slang.expected | 18 | ||||
| -rw-r--r-- | tests/doc/doc.slang | 2 | ||||
| -rw-r--r-- | tests/doc/doc.slang.expected | 375 | ||||
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 66 |
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) |
