ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Diem Move Prover Docgen 输出格式解析:从 TestViz 模块看不同可见性函数的文档生成

Diem Move Prover Docgen 输出格式解析:从 TestViz 模块看不同可见性函数的文档生成 Diem Move Prover Docgen 输出格式解析从 TestViz 模块看不同可见性函数的文档生成【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diem本指南以 Diem 仓库中 Move Prover Docgen 的基线测试输出 different_visbilities.spec_inline.md 为核心样本系统拆解文档生成器Docgen为 Move 模块生成的 Markdown 文档结构、锚点与目录机制、函数可见性对文档内容的影响以及对应的命令行与配置选项。读完本文你将能读懂并复现 Docgen 生成的模块文档理解public、public(script)、私有函数在文档中的呈现差异并掌握如何通过源码与测试基线验证文档生成的正确性。关联文档的定位一份 Docgen 基线测试输出需要先说明本文所依据的样本文档是什么。different_visbilities.spec_inline.md并不是一份手写教程而是 Diem 仓库中Docgen 测试套件的期望输出基线baseline测试工具先对 Move 源文件运行文档生成器再将生成结果与这份基线文件逐字比对从而验证生成器行为没有回归。相关文件均位于 language/move-prover/docgen 目录下测试输入different_visbilities.move —— 定义了包含三种可见性函数的TestViz模块期望输出本文主体different_visbilities.spec_inline.md ——specs_inlinedtrue、折叠实现区details模式同源另两个变体different_visbilities.spec_separate.md 与 different_visbilities.spec_inline_no_fold.md测试驱动testsuite.rs生成器实现docgen.rs用户手册doc/user/docgen.md。从测试套件 testsuite.rs 的FLAGS可以看到Docgen 内嵌于 Move Prover 中通过--docgen开关启用并依赖--dependency../../move-stdlib/modules与--dependency../../diem-framework/modules提供标准库与框架依赖。源头模块TestViz 与三种函数可见性生成这份文档的 Move 源文件很短却刻意覆盖了 Move 语言函数可见性的三种典型形态见 different_visbilities.moveaddress 0x2 { module TestViz { /// This is a public function public fun this_is_a_public_fun() { } // /// This is a public friend function // public(friend) fun this_is_a_public_friend_fun() {} /// This is a public script function public(script) fun this_is_a_public_script_fun() {} /// This is a private function fun this_is_a_private_fun() {} } }三个被测试的函数分别是函数可见性关键字文档注释this_is_a_public_funpublic fun/// This is a public functionthis_is_a_public_script_funpublic(script) fun/// This is a public script functionthis_is_a_private_funfun模块私有/// This is a private function值得注意源文件中被注释掉的public(friend) fun this_is_a_public_friend_fun是测试作者留下的痕迹说明该用例意在对照不同可见性在文档中的渲染由于被注释它不会出现在生成文档中。三处///注释正是 Docgen 读取并写入文档正文的文档注释详见后文文档注释书写规范一节。生成文档的结构逐段解读下面以基线 different_visbilities.spec_inline.md 为准逐段还原其完整内容并解释每一部分的生成机制。模块锚点与一级标题文档以 HTML 锚点与一级标题开头a name0x2_TestViz/a # Module 0x2::TestViz锚点由 docgen.rs 的make_label_for_module生成取模块全名含地址0x2::TestViz将::替换为_得到0x2_TestViz。标题级别则由 section_header 控制section_level_start默认 1加上当前嵌套深度模块层为 0因此模块标题是单个#而后续函数小节为##。自动生成的模块目录紧随标题之后是 Docgen 自动生成的目录- [Function this_is_a_public_fun](#0x2_TestViz_this_is_a_public_fun) - [Function this_is_a_public_script_fun](#0x2_TestViz_this_is_a_public_script_fun) - [Function this_is_a_private_fun](#0x2_TestViz_this_is_a_private_fun)目录条目由 gen_toc 生成每个条目的锚点格式为{模块标签}_{条目名}即0x2_TestViz_this_is_a_public_fun等见label_for_module_item的实现docgen.rs。条目的可见深度由toc_depth默认 3控制函数按源文件中的出现顺序按位置排序依次列出。模块使用信息代码块目录之后是一个空代码块precode/code/pre这并非噪声而是使用信息区域Docgen 会枚举当前模块在字节码层面使用到的其他模块并输出use 模块;语句见 docgen.rs。TestViz没有任何use声明因此该代码块为空。如果一个模块依赖了其他模块这里就会列出对应的use行。函数小节签名、文档注释与折叠的实现每个函数生成一个##小节目录以第一个函数为例完整结构如下a name0x2_TestViz_this_is_a_public_fun/a ## Function this_is_a_public_fun This is a public function precodebpublic/b bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_funthis_is_a_public_fun/a() /code/pre details summaryImplementation/summary precodebpublic/b bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_funthis_is_a_public_fun/a() { } /code/pre /details组成要素包括锚点a name0x2_TestViz_this_is_a_public_fun/a供目录与交叉引用跳转小节标题## Function \this_is_a_public_fun文档注释正文This is a public function直接来自源文件中的///注释函数签名代码块由function_header_displaydocgen.rs生成包含可见性关键字、类型参数、参数列表与返回类型折叠的实现代码块detailssummaryImplementation/summary.../details包裹原始实现源码由begin_collapsed/end_collapseddocgen.rs输出。三种可见性在文档签名中的呈现三个函数的签名代码块完整继承如下正是这份基线文档的核心内容公开函数public funprecodebpublic/b bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_funthis_is_a_public_fun/a() /code/pre precodebpublic/b bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_funthis_is_a_public_fun/a() { } /code/pre公开脚本函数public(script) funprecodebpublic/b(bscript/b) bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_script_funthis_is_a_public_script_fun/a() /code/pre precodebpublic/b(bscript/b) bfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_public_script_funthis_is_a_public_script_fun/a() {} /code/pre私有函数fun无修饰符precodebfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_private_funthis_is_a_private_fun/a() /code/pre precodebfun/b a hrefdifferent_visbilities.md#0x2_TestViz_this_is_a_private_funthis_is_a_private_fun/a() {} /code/pre可见性字符串由func_env.visibility_str()提供在function_header_display中拼接到fun之前因此public、public(script)会原样出现在签名中私有函数则没有任何前缀。b标签是 Docgen 的代码装饰关键词加粗结果a hrefdifferent_visbilities.md#...则是自动生成的交叉引用——指向该模块自身输出文件different_visbilities.md中的对应锚点详见下文交叉引用一节。可见性过滤私有函数何时进入文档值得注意的是私有函数this_is_a_private_fun在默认情况下不一定会出现在生成的文档中。Docgen 通过 gen_module 中的过滤器控制let funs module_env .get_functions() .filter(|f| self.options.include_private_fun || f.is_exposed()) .sorted_by(|a, b| Ord::cmp(a.get_loc(), b.get_loc())) .collect_vec();即只有include_private_fun为真、或函数本身是暴露公开的才会进入文档。这正是本测试用例专门安排一个私有函数的原因——它用于验证私有函数也能被文档化这条路径。对应到用户手册 doc/user/docgen.md 中的命令行开关开关含义用户手册标注的默认值--doc-include-privatetrue\|false是否包含私有函数false但需要提醒代码层面DocgenOptions的Default实现docgen.rs中include_private_fun: true而测试套件也显式设置了options.docgen.include_private_fun truetestsuite.rs。文档与代码默认值存在差异因此实际使用时建议显式传参不要依赖默认行为。交叉引用与代码装饰机制基线文档中每个标识符都被加工过这正是 Docgen 区别于普通 Markdown 渲染器的关键能力实现在 docgen.rs关键字加粗public、fun、script等 Move 关键字含WEAK_KEYWORDS中的 spec 语言关键字被包裹为b.../b标识符超链接resolve_to_label采用启发式解析——优先尝试0xN::Module::item形式的全限定名也支持Self::item、Module::item与裸名裸名只有后跟(或函数调用/泛型实例化时才解析为函数引用以避免把字段名误链为函数HTML 转义、分别转义为lt;、gt;保证签名在precode块内正确显示跨文件引用ref_for_moduledocgen.rs将引用渲染为目标文件#锚点形式。对 TestViz 而言其输出文件由compute_output_file计算——源文件different_visbilities.move的扩展名替换为.mddocgen.rs于是所有引用都指向different_visbilities.md#0x2_TestViz_...。三种基线变体inline / separate / no-fold同一个测试输入在 testsuite.rs 中会以三组不同选项各生成一份基线基线文件specs_inlinedcollapsed_sections差异点different_visbilities.spec_inline.mdtruetrue实现区用details/summary折叠different_visbilities.spec_separate.mdfalsetruespec 独立成节因本模块无 spec输出与 inline 几乎一致different_visbilities.spec_inline_no_fold.mdtruefalse折叠关闭实现区标题渲染为##### Implementation对比三个文件可验证collapsed_sections的具体行为开启时begin_collapsed输出detailssummaryImplementation/summarydocgen.rs关闭时则退化为硬编码的##### Implementation五级标题。由于TestViz没有任何spec块specs_inlined的差异在这里没有体现——若模块带 specinline 模式会把规范内联到对应声明的小节下separate 模式则汇总到文档末尾独立的 Specification 章节见 gen_spec_section。运行 Docgen 生成此类文档若要在自己的 Move 源码上复现同样的文档按用户手册 doc/user/docgen.md 中的方式调用cargo run -p move-prover -- --docgen flags .. sources常用参数-dpathMove 依赖的搜索路径编译用--doc-pathpath已生成文档的搜索路径用于交叉引用--doc-spec-inlinetrue|falsespec 是内联到声明处true默认还是汇总到文末独立章节false--doc-include-impltrue|false是否包含函数实现体默认 true--doc-include-privatetrue|false是否包含私有函数默认 false与源码Default存在差异建议显式指定--outputpath生成文档的输出路径完整选项可通过cargo run -p move-prover -- --help查看。若想直接参与 Docgen 的验证可运行 Docgen 目录下的测试套件datatest_stable会扫描 tests/sources 下所有*.move与*_template.md并用verify_or_update_baseline机制比对或更新基线testsuite.rs。注意仓库为只读环境这里仅说明查看与验证方式不建议在仓库内直接改动基线。文档注释书写规范与 Spec 块归属最后若希望自己写的模块也能生成类似 TestViz 这样结构清晰的文档需要遵循 Docgen 对注释与 spec 块的约定详见 doc/user/docgen.md文档注释以///或/** ... */开头必须置于被注释项之前可作用于模块、结构体、结构体字段、函数、spec 块及 spec 块成员连续多段注释会合并为一个文档块注释内 Markdown支持任意 Markdown建议兼容 GitHub 风格也可使用#小节标题标题会自动降级嵌入当前上下文层级之下代码引用注释中的foo不会解析为当前模块的函数除非写成foo()或Self::fooSpec 块归属无明确目标的 schema 与spec module块会归属于其之前最近的函数/结构体 spec 块否则归属于模块可在函数 spec 之后放一个空spec module {}强制将后续 spec 归属回模块级例如module M { fun f(): T { ... } spec f { aborts_if f_aborts(); ensures result f_result(); } // 以下内容跟随函数 f 的文档 spec fun f_aborts() { .. } spec module {} // 以下内容跟随模块文档 spec fun f_result(): T { .. } }小结通过 different_visbilities.spec_inline.md 这一基线样本可以看到 Diem Move Prover Docgen 的完整输出契约模块锚点与标题、自动目录、使用信息、函数签名与文档注释、折叠实现、关键字加粗与交叉引用。结合 docgen.rs 的实现与 testsuite.rs 的三种选项组合可以准确推断任何模块文档的生成规则——包括public、public(script)与私有函数在文档中的不同呈现以及--doc-include-private、--doc-spec-inline、collapsed_sections等选项如何改变最终输出。对于维护 Move 生态工具链或需要为 Move 模块生成规范 API 文档的开发者这份基线与其配套源码是理解 Docgen 行为最直接的参考实现。【免费下载链接】diemDiem’s mission is to build a trusted and innovative financial network that empowers people and businesses around the world.项目地址: https://gitcode.com/gh_mirrors/di/diem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表