Guidedog マニュアル 0.2.0
言語
このページの内容
Guidedog / ドキュメント 0.2.0

Odin の文書化

Odin ドメインはパッケージ、プロシージャー、型、メンバーに名前付きターゲットを与える。Guidedog は Odin ソースから API ページも生成するが、コンパイラーもパッケージも実行しない。生成したシグネチャにも有用な契約が必要。

オブジェクトの記述

パッケージは、Python モジュールのように後続の記述の文脈を定める。

.. odin:package:: core:strings
   :synopsis: Procedures to manipulate UTF-8 encoded strings.
   :imports: rt=base:runtime

.. odin:procedure:: @(require_results) clone :: proc(s: string, allocator := context.allocator) -> (res: string, err: rt.Allocator_Error) #optional_allocator_error

   Clones a string.

   :param s: The string to be cloned.
   :result res: The cloned string.
   :result err: An allocator error, or ``nil``.

.. odin:struct:: Builder :: struct

   A dynamic byte buffer.

   .. odin:field:: buf: [dynamic]byte

シグネチャは Odin の宣言と同じく一行で書き、そのまま表示する。以下の例は次のように見える。

shapes.Kind :: enum u8
Circle = 1
@(require_results) shapes.area :: proc(side: f32, scale: f32 = 1) -> (a: f32, ok: bool) #optional_ok

正方形を計測します。

パラメーター:

side – 一辺の長さ。

戻り値:
  • a – 面積。

  • ok – 種類が分かっているか。

ディレクティブと受け付けるシグネチャ。

odin:package と odin:currentpackage

core:fmt やプロジェクト配下の readers/sphinx を指定する。オブジェクト名はインポートパスを使う(core:fmt.println)。odin:currentpackage はターゲットを作らず文脈を変え、None は解除する。オプションは :synopsis:、:platform:、:deprecated:、:no-index:、:imports:。最後はシグネチャの別名を alias=package(gd=core rst=readers/rst)で指定し、gd.Node_Id を core.Node_Id に結ぶ。:private: は私有型とプロシージャー群の私有メンバー(State Rules catalog_text)を列挙する。リンク先の説明がないため文字列で表示し、生成ページは自動で列挙する。

odin:procedure(または odin:proc)

name :: proc(params) -> results。名前前の属性(@(require_results))、proc 前の #force_inline、呼出規約(proc "c" (...))、既定引数(x := 1、x: int = 1)、$T 多相引数、.. 可変長、using、#c_vararg、名前付き結果、タグ(#optional_ok)、where 節を扱う。name(params) -> results は短縮形。

odin:procgroup

name :: proc{a, b}:各メンバーは対応するプロシージャーにリンクする。

odin:struct, odin:union, odin:enum, odin:bitset, odin:bitfield, odin:type

Name :: struct($T: typeid) #packed、Name :: union #no_nil {A, B}、Name :: enum u8、Name :: bit_set[Flag; u8]、Name :: bit_field u32。odin:type は distinct 型と別名(Handle :: distinct uintptr、Callback :: proc(x: int) -> bool)を扱う。型の内容にメンバーを記述する。

odin:field と odin:enumerator

型の中では name: Type にタグ(name: string `json:"n"`)やビット幅(low: u8 | 3)を付けられ、列挙子は Name または Name = 3。名前は Type.member となる。

odin:const, odin:var, odin:foreign

NAME :: 64 または NAME : int : 64、name: Type、name := value、name: Type = value。外部インポートは libc "system:c"。

全オブジェクトが Sphinx の :no-index:、:no-index-entry:、:no-contents-entry:、:no-typesetting: を受け付ける。独自には :package:(別パッケージで説明)、:private: と :deprecated: message(シグネチャになければ @(private) と @(deprecated="message") を表示)、:availability: Windows, Linux(本文先頭に対応先)、:foreign: libc(外部ブロックの手続き)がある。複数行のシグネチャはターゲットで異なる同じオブジェクトを表し、ID と索引は最初だけに付く。

型の位置にある名前は、まずシグネチャのパッケージと型で、次にそのまま検索してリンクする。組み込み型(int、string、rawptr、typeid、any など)、予約語、多相名($T と以後の T、外側の型を含む)、配列長、既定値、定数、タグ、where 節はそのまま表示し、リンクにしない。

ロールと ID

:odin:pkg:、:odin:proc:、:odin:type:(構造体、共用体、列挙、ビット集合・フィールドなど)、:odin:const:、:odin:var:、:odin:field:、:odin:enumerator:、:odin:obj:(全種類)がリンクする。Python 同様 ~ は末尾だけを表示し(:odin:proc:`~core:fmt.println` は println)、先頭の . は名前の末尾を探す。参照元の型とパッケージ、そのままの名前、パスの : や / の後の順に検索する。fmt.println は core:fmt.println、sphinx.Config は readers/sphinx.Config を見つける。Odin と同じ末尾のパッケージ名で、:imports: の別名を優先する。default-domain:: odin または primary_domain = "odin" なら odin: は省ける。

ID は odin- と完全名に Sphinx の make_id を適用する。例は odin-core-fmt.println、odin-readers-sphinx.Config.docname。Python 同様大小文字とドットを保ち、パスの : と / はハイフンになる。URL で読め、ビルド間で安定し、末尾同名のパッケージも区別する。パッケージ ID は odin-package- とパス。索引は「println (procedure in core:fmt)」。objects.inv は odin と種別(odin:procedure、odin:struct、odin:field など)で全オブジェクトを、Sphinx のモジュール同様パッケージを先に列挙する。

内容中の情報フィールドは他のドメイン同様にまとめる。:param name:(:type name: と併用)、名前付き結果の :result name:、:returns:、:rtype:。

ソースからの生成

ソースフォルダーからの相対位置でパッケージを指定する。

odin_autoapi_dirs = ["../src"]
odin_collections = {core = "/usr/local/lib/odin/core"}  # optional

odin_autoapi_dirs 配下は相対パスで命名する(src/shapes/round は shapes/round)。コレクション内は Odin のインポート名(core:strings)を使う。生成ディレクティブは autodoc と同様に動く。

.. odin:autopackage:: shapes
   :members:
   :undoc-members:
   :member-order: groupwise

.. odin:autoproc:: shapes.area
.. odin:autotype:: Shape

odin:autopackage はパッケージと文書コメントを、:members: で宣言全てまたは指定分も出力する。odin:autoproc、odin:autoprocgroup、odin:autotype、odin:autoconst、odin:autovar は現在のパッケージ名または package.name の宣言一つを出す。オプションは :members:、:undoc-members:、:private-members:(通常除く @(private))、:exclude-members:、:member-order:(既定の source はファイル名と位置順、alphabetical、groupwise は「Types」「Procedures」「Procedure groups」「Constants」「Variables」「Foreign imports」で分類)、:no-index:。

文書コメントは宣言直上の // 行や /* */ ブロック、フィールドや列挙子の行末コメント。プレーンテキストを次の規則で reStructuredText にする。

  • 段落は段落に、- item の行はリストになる。
  • 空行またはコロンで終わる行(Example:)の後の字下げブロックは code-block:: odin、Output: の後は text になる。段落行直後のテキストより深い字下げの行は、その段落を続ける。
  • Inputs: の - name: text 項目は :param name:、Returns: は :result name:(名前なしなら :returns:)になる。Odin のコアライブラリーと同じ書式だ。
  • NOTE: または WARNING: で始まる行は注記または警告になる。
  • `code` はリテラル。reStructuredText が記法と読む他の文字(*、|、語末の _ など)はエスケープし、コメントをそのまま表示して警告を出さない。

API ページ

odin_autoapi_dirs を設定すると、各パッケージに sphinx-autoapi のようなページを読み取り時に生成する。api/shapes は odin_autoapi_options 付きの odin:autopackage:: shapes、api/index は各パッケージと概要を含む。toctree、検索、総索引、singlehtml、PDF に入るプロジェクト文書だが、ソースフォルダーには書かない。設定は次の通り。

odin_autoapi_dirs

ページを作るパッケージのフォルダーをソースからの相対位置で指定する。その配下と odin_collections のファイルだけを読み、外へ向かうリンクは拒否する。

odin_collections

core:strings などの引数に使う、コレクション名とフォルダーの表。これらのパッケージにはページを作らない。

odin_autoapi_root

ページのフォルダー。既定は "api"。同名のソース文書があればそちらを残し、警告する。

odin_autoapi_options

既定は ["members", "undoc-members"]。private-members も追加できる。

odin_autoapi_member_order

"source"(既定)、"alphabetical"、"groupwise"。

odin_autoapi_add_toctree_entry

true(既定):api/index をルート文書の最初の toctree に加える。

odin_autoapi_generate_api_docs

true(既定)。false はディレクティブ用にだけフォルダーを読む。

文書化しないパッケージの型(core:io.Writer)にはリンクできない。-n では nitpick_ignore_regex = [["odin:type", "(core|base):.*"]] で抑制する。Guidedog の docs/api もこの設定を使う。

プラットフォーム

Odin と同じファイル判定で、パッケージの全ターゲットを文書化する。*_windows.odin、*_linux_arm64.odin、*_amd64.odin は該当先のみ。#+build linux, darwin、#+build !windows(旧 //+build も)が絞る。ファイルの when ODIN_OS == .Windows が ODIN_OS と ODIN_ARCH の比較だけなら、分岐と else を対応先へ分ける。*_test.odin と #+ignore は除く。全ターゲット共通の宣言は一回、部分対応は「Availability: Windows」などで示す。異なるシグネチャはそれぞれ対応先付きで示し、ID は最初だけ。部分対応のパッケージは :platform: で示す。

再ビルド

読んだ各 Odin ファイルはページの依存となる。ソース編集後は、そのパッケージを説明するページだけを再読する。パッケージの追加・削除・概要変更時は索引も再読する。guidedog serve は HTML を返す前に odin_autoapi_dirs と odin_collections の変更時刻を調べる。編集後にブラウザーを更新する。

制約

  • ソースは解析だけで、コンパイルや型検査はしない。型と定数値はそのまま表示し、100文字超の値は省く。推論もない。A :: B の型か定数かは名前で判定し、全大文字でない大文字始まりの名前や組み込み型を型とする。
  • when の条件は ODIN_OS と ODIN_ARCH の比較以外は評価せず、両方の分岐を記載する。
  • 私有型は文字列で示す。:private-members: がなければリンク先の項目がないためだ。生成したパッケージは :private: に列挙するので -n でも報告しない。
  • core:odin/parser は #optional_ok と where を併用するプロシージャーを拒否する。そのファイルを報告し、読めた部分は文書化する。
  • Odin のパーサーは深い入れ子で多くのスタックを要し、数百の括弧でスレッドをあふれさせる。実用を大きく超えるファイル(括弧・型が約50段、一連の else が約千個)は odin.autodoc.nesting で除き、パッケージの残りは記載する。when の &&、||、! は64段まで評価し、それ以上は未評価とする。