Guidedog Handbuch 0.2.0
Sprache
Auf dieser Seite
Guidedog / Dokumentation 0.2.0

Odin dokumentieren

Die Odin-Domäne gibt Paketen, Prozeduren, Typen und Mitgliedern benannte Ziele. Guidedog erzeugt API-Seiten durch Parsen des Odin-Codes, ohne Compiler oder Paket auszuführen. Auch generierte Signaturen benötigen einen nützlichen Vertrag.

Objekte beschreiben

Ein Paket legt den Kontext für nachfolgende Angaben fest, wie ein Python-Modul:

.. 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

Signaturen werden wie Odin-Deklarationen in einer Zeile geschrieben und ebenso angezeigt. Die folgenden Beispiele sehen so aus:

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

Vermisst ein Quadrat.

Parameter:

side – Seine Seitenlänge.

Rückgabe:
  • a – Seine Fläche.

  • ok – Ob seine Art bekannt ist.

Direktiven und die akzeptierten Signaturen:

odin:package und odin:currentpackage

Akzeptiert core:fmt oder einen Pfad unter den Projektwurzeln wie readers/sphinx. Objektnamen nutzen den Importpfad: core:fmt.println. odin:currentpackage ändert den Kontext ohne Ziel; None hebt ihn auf. Optionen: :synopsis:, :platform:, :deprecated:, :no-index: und :imports: für Importaliaspaare alias=package (gd=core rst=readers/rst), sodass gd.Node_Id auf core.Node_Id verweist. :private: nennt private Typen und private Gruppenmitglieder (State Rules catalog_text). Ohne verlinkbare Beschreibung erscheinen sie als Text; generierte Seiten listen sie automatisch.

odin:procedure (oder odin:proc)

name :: proc(params) -> results unterstützt Attribute vor dem Namen (@(require_results)), #force_inline vor proc, Aufrufkonventionen (proc "c" (...)), Standardparameter (x := 1, x: int = 1), polymorphe $T-Parameter, ..-Variadik, using, #c_vararg, benannte Ergebnisse, Tags (#optional_ok) und where. name(params) -> results ist die Kurzform.

odin:procgroup

name :: proc{a, b}: Jedes Mitglied verlinkt auf seine Prozedur.

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 unterstützt eigenständige Typen und Aliasse (Handle :: distinct uintptr, Callback :: proc(x: int) -> bool). Der Typinhalt enthält seine Mitglieder.

odin:field und odin:enumerator

Innerhalb eines Typs: name: Type mit Tag (name: string `json:"n"`) oder Bitbreite (low: u8 | 3) sowie Name oder Name = 3. Ihre Namen lauten Type.member.

odin:const, odin:var, odin:foreign

NAME :: 64 oder NAME : int : 64; name: Type, name := value oder name: Type = value; libc "system:c" für einen Fremdimport.

Alle Objekte akzeptieren Sphinx-Optionen: :no-index:, :no-index-entry:, :no-contents-entry:, :no-typesetting:. Hinzu kommen :package: (anderes Paket), :private: und :deprecated: message (zeigen bei fehlendem Signaturattribut @(private) und @(deprecated="message")), :availability: Windows, Linux (erste Inhaltszeile mit Verfügbarkeit) sowie :foreign: libc (Fremdblockprozedur). Mehrere Signaturzeilen beschreiben ein Objekt für verschiedene Ziele; nur die erste erhält ID und Indexeintrag.

Namen an Typstellen werden zuerst im Paket und Typ der Signatur, dann wie geschrieben aufgelöst. Eingebaute Typen (int, string, rawptr, typeid, any usw.), Schlüsselwörter, polymorphe Namen ($T und folgendes T, auch im umgebenden Typ), Arraylängen, Standardwerte, Konstanten, Tags und where-Klauseln bleiben unverlinkter Originaltext.

Rollen und IDs

:odin:pkg:, :odin:proc:, :odin:type: (Strukturen, Unions, Aufzählungen, Bitmengen und -felder usw.), :odin:const:, :odin:var:, :odin:field:, :odin:enumerator: und :odin:obj: (alle) verlinken Objekte. Wie bei Python zeigt ~ nur das Ende (:odin:proc:`~core:fmt.println` zeigt println); ein führendes . sucht Namensenden. Gesucht wird im Kontexttyp und -paket, nach dem geschriebenen Namen und nach dem Pfadteil hinter : oder /. So findet fmt.println core:fmt.println und sphinx.Config readers/sphinx.Config, entsprechend Odin. Aliasse aus :imports: gehen vor. Bei default-domain:: odin oder primary_domain = "odin" entfällt odin:.

Objekt-IDs entstehen mit Sphinx-make_id aus odin- und dem vollständigen Namen: odin-core-fmt.println, odin-readers-sphinx.Config.docname. Großschreibung und Punkte bleiben; : und / werden Bindestriche. IDs sind lesbar, buildstabil und unterscheiden Pakete mit gleichem Endnamen. Paket-IDs bestehen aus odin-package- und Pfad. Indexeinträge lauten etwa „println (procedure in core:fmt)“. objects.inv listet alle unter odin und Typ (odin:procedure, odin:struct, odin:field usw.), Pakete zuerst wie Sphinx-Module.

Informationsfelder werden wie in anderen Domänen gruppiert: :param name: mit :type name:, :result name: für benannte Ergebnisse sowie :returns: und :rtype:.

Aus Quelltext generieren

Geben Sie die Paketverzeichnisse relativ zum Quellordner an:

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

Unter odin_autoapi_dirs gilt der relative Pfad als Name (src/shapes/round wird shapes/round); in Sammlungen der Odin-Importname (core:strings). Die Generierungsdirektiven funktionieren dann wie autodoc:

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

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

odin:autopackage schreibt Paket und Dokumentkommentar sowie mit :members: alle oder ausgewählte Deklarationen. odin:autoproc, odin:autoprocgroup, odin:autotype, odin:autoconst und odin:autovar schreiben eine Deklaration im Kontext oder als package.name. Optionen: :members:, :undoc-members:, :private-members: (sonst ausgelassene @(private)), :exclude-members:, :member-order: (Standard source nach Datei und Position; alphabetical; groupwise mit „Types“, „Procedures“, „Procedure groups“, „Constants“, „Variables“, „Foreign imports“) und :no-index:.

Dokumentkommentare sind //-Zeilen oder /* */-Blöcke direkt über Deklarationen sowie Zeilenendkommentare von Feldern oder Enumeratoren. Ihr Klartext wird so zu reStructuredText:

  • Absätze bleiben Absätze; eine Folge von - item-Zeilen bleibt eine Liste.
  • Ein eingerückter Block nach einer Leerzeile oder Doppelpunktzeile (Example:) wird code-block:: odin, nach Output: dagegen text. Eine stärker als der Text unmittelbar nach einer Absatzzeile eingerückte Zeile setzt den Absatz fort.
  • Inputs: mit - name: text wird zu :param name:-Feldern; Returns: zu :result name: oder ohne Namen :returns:, entsprechend der Odin-Kernbibliothek.
  • Eine mit NOTE: oder WARNING: beginnende Zeile wird zur Anmerkung oder Warnung.
  • `code` ist Literaltext. Andere Markupzeichen von reStructuredText (*, |, _ am Wortende usw.) werden escaped, sodass der Kommentar unverändert erscheint und keine Warnung erzeugt.

API-Seiten

Mit odin_autoapi_dirs erhält jedes Paket beim Lesen eine eigene Seite wie bei sphinx-autoapi. api/shapes enthält odin:autopackage:: shapes mit odin_autoapi_options; api/index listet Pakete samt Kurzbeschreibung. Die Seiten gehören zu toctree, Suche, Gesamtindex, singlehtml und PDF, werden aber nie in den Quellordner geschrieben. Einstellungen:

odin_autoapi_dirs

Paketordner für die Seitengenerierung, relativ zum Quellordner. Nur Dateien darunter und unter odin_collections werden gelesen; herausführende Links werden abgelehnt.

odin_collections

Tabelle von Sammlungsnamen und Ordnern für Direktivenargumente wie core:strings. Diese Pakete erhalten keine Seiten.

odin_autoapi_root

Der Seitenordner, standardmäßig "api". Ein gleichnamiges Quelldokument behält seinen Platz; eine Warnung wird ausgegeben.

odin_autoapi_options

Standard: ["members", "undoc-members"]; private-members lässt sich ergänzen.

odin_autoapi_member_order

"source" (Standard), "alphabetical" oder "groupwise".

odin_autoapi_add_toctree_entry

true (Standard): api/index wird dem ersten toctree des Hauptdokuments hinzugefügt.

odin_autoapi_generate_api_docs

true (Standard); bei false werden die Ordner nur für Direktiven gelesen.

Typen undokumentierter Pakete (core:io.Writer) sind nicht verlinkbar. Unter -n unterdrückt nitpick_ignore_regex = [["odin:type", "(core|base):.*"]] diese Meldungen. Auch Guidedogs docs/api wird so gebaut.

Plattformen

Dokumentiert werden Odins Build-Ziele nach seinen Dateiregeln. *_windows.odin, *_linux_arm64.odin und *_amd64.odin gelten nur für entsprechende Ziele. #+build linux, darwin und #+build !windows (auch altes //+build) schränken weiter ein. Ein dateiweites when ODIN_OS == .Windows wird samt else nach Zielen aufgeteilt, wenn es nur ODIN_OS und ODIN_ARCH vergleicht. *_test.odin und #+ignore entfallen. Gemeinsame Deklarationen erscheinen einmal, teilweise verfügbare mit „Availability: Windows“. Verschiedene Signaturen erscheinen je Zielmenge; nur die erste erhält eine ID. Eingeschränkte Pakete nennen :platform:.

Erneuter Build

Jede gelesene Odin-Datei ist eine Seitenabhängigkeit. Nach Quelländerungen werden nur Seiten des betroffenen Pakets neu gelesen. Der Paketindex wird bei Hinzufügen, Entfernen oder geänderter Kurzbeschreibung erneuert. guidedog serve prüft vor HTML-Auslieferung die Änderungszeiten in odin_autoapi_dirs und odin_collections. Laden Sie nach Änderungen die Browserseite neu.

Grenzen

  • Der Code wird nur geparst, nicht kompiliert oder typgeprüft. Typen und Konstantenwerte erscheinen wie geschrieben; Werte über 100 Zeichen entfallen. Es gibt keine Inferenz. Bei A :: B entscheidet der Name: Ein groß beginnender, nicht vollständig großgeschriebener Name oder ein eingebauter Typ gilt als Typ.
  • when-Bedingungen außer Vergleichen von ODIN_OS und ODIN_ARCH werden nicht ausgewertet; beide Zweige werden dokumentiert.
  • Private Typen erscheinen als Text, da sie ohne :private-members: keine Einträge haben. Das generierte Paket nennt sie in :private:, sodass -n sie nicht meldet.
  • core:odin/parser lehnt Prozeduren mit #optional_ok und einer where-Klausel ab. Die Datei wird gemeldet; lesbare Teile werden dennoch dokumentiert.
  • Odins Parser braucht bei tiefer Verschachtelung viel Stack; einige hundert Klammern können einen Thread überfordern. Dateien weit jenseits realer Tiefe (etwa 50 Klammer- oder Typebenen oder tausend else-Glieder) entfallen mit odin.autodoc.nesting. Der Rest wird dokumentiert. when wertet &&, || und ! bis 64 Ebenen aus; längere Bedingungen gelten als unausgewertet.